Trending: Add graph with statistics 51/33151/15
authorTibor Frank <tifrank@cisco.com>
Tue, 13 Jul 2021 06:47:31 +0000 (08:47 +0200)
committerTibor Frank <tifrank@cisco.com>
Thu, 22 Jul 2021 09:00:50 +0000 (09:00 +0000)
- x-axis: time [MM-DD]
- y-axis: nr of passed/failed tests
- y-axis: build duration

Change-Id: I269af5a728a32d02ffcdecc7e25138ad1a183c4b
Signed-off-by: Tibor Frank <tifrank@cisco.com>
docs/cpta/index.rst
docs/cpta/stats/dpdk_mrr.rst [new file with mode: 0644]
docs/cpta/stats/vpp_mrr.rst [new file with mode: 0644]
docs/cpta/stats/vpp_ndrpdr.rst [new file with mode: 0644]
resources/tools/presentation/generator_alerts.py
resources/tools/presentation/generator_plots.py
resources/tools/presentation/generator_tables.py
resources/tools/presentation/input_data_parser.py
resources/tools/presentation/specifications/trending/elements.yaml
resources/tools/presentation/specifications/trending/layouts.yaml

index 6dc3a3c..764c5c1 100644 (file)
@@ -54,6 +54,14 @@ analysis and anomaly detection methodology.
     ndrpdr_trending/ipsec
     ndrpdr_trending/vts
 
+.. toctree::
+    :maxdepth: 2
+    :caption: Statistics
+
+    stats/vpp_mrr
+    stats/vpp_ndrpdr
+    stats/dpdk_mrr
+
 .. toctree::
     :maxdepth: 2
     :caption: Performance Data
diff --git a/docs/cpta/stats/dpdk_mrr.rst b/docs/cpta/stats/dpdk_mrr.rst
new file mode 100644 (file)
index 0000000..23f7cfb
--- /dev/null
@@ -0,0 +1,74 @@
+DPDK MRR
+========
+
+2n-clx
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-dpdk-perf-mrr-weekly-master-2n-clx" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-dpdk-2n-clx-mrr.html"></iframe>
+    <p><br></p>
+    </center>
+
+2n-skx
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-dpdk-perf-mrr-weekly-master-2n-skx" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-dpdk-2n-skx-mrr.html"></iframe>
+    <p><br></p>
+    </center>
+
+3n-skx
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-dpdk-perf-mrr-weekly-master-3n-skx" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-dpdk-3n-skx-mrr.html"></iframe>
+    <p><br></p>
+    </center>
+
+2n-zn2
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-mrr-daily-master-2n-zn2" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-2n-zn2-mrr.html"></iframe>
+    <p><br></p>
+    </center>
+
+3n-tsh
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-mrr-daily-master-3n-tsh" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-3n-tsh-mrr.html"></iframe>
+    <p><br></p>
+    </center>
+
+2n-tx2
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-mrr-daily-master-2n-tx2" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-2n-tx2-mrr.html"></iframe>
+    <p><br></p>
+    </center>
diff --git a/docs/cpta/stats/vpp_mrr.rst b/docs/cpta/stats/vpp_mrr.rst
new file mode 100644 (file)
index 0000000..b4700c8
--- /dev/null
@@ -0,0 +1,98 @@
+VPP MRR
+=======
+
+2n-clx
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-mrr-daily-master-2n-clx" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-2n-clx-mrr.html"></iframe>
+    <p><br></p>
+    </center>
+
+2n-skx
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-mrr-daily-master-2n-skx" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-2n-skx-mrr.html"></iframe>
+    <p><br></p>
+    </center>
+
+3n-skx
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-mrr-daily-master-3n-skx" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-3n-skx-mrr.html"></iframe>
+    <p><br></p>
+    </center>
+
+2n-zn2
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-mrr-daily-master-2n-zn2" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-2n-zn2-mrr.html"></iframe>
+    <p><br></p>
+    </center>
+
+3n-tsh
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-mrr-daily-master-3n-tsh" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-3n-tsh-mrr.html"></iframe>
+    <p><br></p>
+    </center>
+
+2n-tx2
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-mrr-daily-master-2n-tx2" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-2n-tx2-mrr.html"></iframe>
+    <p><br></p>
+    </center>
+
+2n-dnv
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-mrr-daily-master-2n-dnv" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-2n-dnv-mrr.html"></iframe>
+    <p><br></p>
+    </center>
+
+3n-dnv
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-mrr-daily-master-3n-dnv" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-3n-dnv-mrr.html"></iframe>
+    <p><br></p>
+    </center>
diff --git a/docs/cpta/stats/vpp_ndrpdr.rst b/docs/cpta/stats/vpp_ndrpdr.rst
new file mode 100644 (file)
index 0000000..7cb6fe2
--- /dev/null
@@ -0,0 +1,38 @@
+VPP NDRPDR
+==========
+
+2n-clx
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-ndrpdr-weekly-master-2n-clx" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-2n-clx-ndrpdr.html"></iframe>
+    <p><br></p>
+    </center>
+
+2n-skx
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-ndrpdr-weekly-master-2n-skx" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-2n-skx-ndrpdr.html"></iframe>
+    <p><br></p>
+    </center>
+
+3n-skx
+------
+
+.. raw:: html
+
+    <center>
+    Links to builds:
+    <a href="https://jenkins.fd.io/view/csit/job/csit-vpp-perf-ndrpdr-weekly-master-3n-skx" target="_blank">csit-ref</a>
+    <iframe width="1100" height="800" frameborder="0" scrolling="no" src="../_static/vpp/stats-3n-skx-ndrpdr.html"></iframe>
+    <p><br></p>
+    </center>
index a71b775..4dd78fe 100644 (file)
@@ -246,7 +246,7 @@ class Alerting:
         :type sort: bool
         :returns: CSIT build number, VPP version, Number of passed tests,
             Number of failed tests, Compressed failed tests.
-        :rtype: tuple(str, str, int, int, OrderedDict)
+        :rtype: tuple(str, str, int, int, str, OrderedDict)
         """
 
         directory = self.configs[alert[u"way"]][u"output-dir"]
@@ -268,6 +268,10 @@ class Alerting:
                     if idx == 3:
                         failed = line[:-1]
                         continue
+                    if idx == 4:
+                        minutes = int(line[:-1]) // 60000
+                        duration = f"{(minutes // 60):02d}:{(minutes % 60):02d}"
+                        continue
                     try:
                         test = line[:-1].split(u'-')
                         name = u'-'.join(test[3:-1])
@@ -285,14 +289,14 @@ class Alerting:
                         failed_tests[name][u"cores"].append(test[2])
         except IOError:
             logging.error(f"No such file or directory: {file_path}")
-            return None, None, None, None, None
+            return None, None, None, None, None, None
         if sort:
             sorted_failed_tests = OrderedDict()
             for key in sorted(failed_tests.keys()):
                 sorted_failed_tests[key] = failed_tests[key]
-            return build, version, passed, failed, sorted_failed_tests
+            return build, version, passed, failed, duration, sorted_failed_tests
 
-        return build, version, passed, failed, failed_tests
+        return build, version, passed, failed, duration, failed_tests
 
     def _list_gressions(self, alert, idx, header, re_pro):
         """Create a file with regressions or progressions for the test set
@@ -352,7 +356,7 @@ class Alerting:
             try:
                 groups = re.search(
                     re.compile(
-                        r'((vpp|dpdk)-\dn-(skx|clx|hsw|tsh|dnv|zn2|tx2)-.*)'
+                        r'((vpp|dpdk)-\dn-(skx|clx|tsh|dnv|zn2|tx2)-.*)'
                     ),
                     test_set
                 )
@@ -363,7 +367,7 @@ class Alerting:
                     f"The test set {test_set} does not include information "
                     f"about test bed. Using empty string instead."
                 )
-            build, version, passed, failed, failed_tests = \
+            build, version, passed, failed, duration, failed_tests = \
                 self._get_compressed_failed_tests(alert, test_set)
             if build is None:
                 text += (
@@ -373,8 +377,11 @@ class Alerting:
                 )
                 continue
             text += (
-                f"\n\n{test_set_short}, {failed} tests failed, {passed} tests "
-                f"passed, CSIT build: {alert[u'urls'][idx]}/{build}, "
+                f"\n\n{test_set_short}, "
+                f"{failed} tests failed, "
+                f"{passed} tests passed, "
+                f"duration: {duration}, "
+                f"CSIT build: {alert[u'urls'][idx]}/{build}, "
                 f"{device} version: {version}\n\n"
             )
 
index f03a57f..f273aeb 100644 (file)
@@ -19,6 +19,7 @@ import re
 import logging
 
 from collections import OrderedDict
+from datetime import datetime
 from copy import deepcopy
 from math import log
 
@@ -27,6 +28,7 @@ import hdrh.codec
 import pandas as pd
 import plotly.offline as ploff
 import plotly.graph_objs as plgo
+import plotly.exceptions as plerr
 
 from plotly.exceptions import PlotlyError
 
@@ -84,7 +86,8 @@ def generate_plots(spec, data):
         u"plot_hdrh_lat_by_percentile": plot_hdrh_lat_by_percentile,
         u"plot_hdrh_lat_by_percentile_x_log": plot_hdrh_lat_by_percentile_x_log,
         u"plot_mrr_box_name": plot_mrr_box_name,
-        u"plot_ndrpdr_box_name": plot_ndrpdr_box_name
+        u"plot_ndrpdr_box_name": plot_ndrpdr_box_name,
+        u"plot_statistics": plot_statistics
     }
 
     logging.info(u"Generating the plots ...")
@@ -102,6 +105,121 @@ def generate_plots(spec, data):
     logging.info(u"Done.")
 
 
+def plot_statistics(plot, input_data):
+    """Generate the plot(s) with algorithm: plot_statistics
+    specified in the specification file.
+
+    :param plot: Plot to generate.
+    :param input_data: Data to process.
+    :type plot: pandas.Series
+    :type input_data: InputData
+    """
+
+    data_x = list()
+    data_y_pass = list()
+    data_y_fail = list()
+    data_y_duration = list()
+    hover_text = list()
+    hover_str = (
+        u"date: {date}<br>"
+        u"passed: {passed}<br>"
+        u"failed: {failed}<br>"
+        u"duration: {duration}<br>"
+        u"{sut}-ref: {build}<br>"
+        u"csit-ref: {test}-{period}-build-{build_nr}<br>"
+        u"testbed: {testbed}"
+    )
+    for job, builds in plot[u"data"].items():
+        for build_nr in builds:
+            try:
+                meta = input_data.metadata(job, str(build_nr))
+                generated = meta[u"generated"]
+                date = datetime(
+                    int(generated[0:4]),
+                    int(generated[4:6]),
+                    int(generated[6:8]),
+                    int(generated[9:11]),
+                    int(generated[12:])
+                )
+                d_y_pass = meta[u"tests_passed"]
+                d_y_fail = meta[u"tests_failed"]
+                minutes = meta[u"elapsedtime"] // 60000
+                duration = f"{(minutes // 60):02d}:{(minutes % 60):02d}"
+                version = meta[u"version"]
+            except (KeyError, IndexError, ValueError, AttributeError):
+                continue
+            data_x.append(date)
+            data_y_pass.append(d_y_pass)
+            data_y_fail.append(d_y_fail)
+            data_y_duration.append(minutes)
+            hover_text.append(hover_str.format(
+                date=date,
+                passed=d_y_pass,
+                failed=d_y_fail,
+                duration=duration,
+                sut=u"vpp" if u"vpp" in job else u"dpdk",
+                build=version,
+                test=u"mrr" if u"mrr" in job else u"ndrpdr",
+                period=u"daily" if u"daily" in job else u"weekly",
+                build_nr=build_nr,
+                testbed=meta[u"testbed"]
+            ))
+
+    traces = [
+        plgo.Bar(
+            x=data_x,
+            y=data_y_pass,
+            name=u"Passed",
+            text=hover_text,
+            hoverinfo=u"text"
+        ),
+        plgo.Bar(
+            x=data_x,
+            y=data_y_fail,
+            name=u"Failed",
+            text=hover_text,
+            hoverinfo=u"text"),
+        plgo.Scatter(
+            x=data_x,
+            y=data_y_duration,
+            name=u"Duration",
+            yaxis=u"y2",
+            text=hover_text,
+            hoverinfo=u"text"
+        )
+    ]
+
+    name_file = f"{plot[u'output-file']}.html"
+
+    logging.info(f"    Writing the file {name_file}")
+    plpl = plgo.Figure(data=traces, layout=plot[u"layout"])
+    tickvals = [min(data_y_duration), max(data_y_duration)]
+    step = (tickvals[1] - tickvals[0]) / 6
+    for i in range(6):
+        tickvals.append(int(tickvals[0] + step * (i + 1)))
+    plpl.update_layout(
+        yaxis2=dict(
+            title=u"Duration [hh:mm]",
+            anchor=u"x",
+            overlaying=u"y",
+            side=u"right",
+            tickmode=u"array",
+            tickvals=tickvals,
+            ticktext=[f"{(val // 60):02d}:{(val % 60):02d}" for val in tickvals]
+        )
+    )
+    plpl.update_layout(barmode=u"stack")
+    try:
+        ploff.plot(
+            plpl,
+            show_link=False,
+            auto_open=False,
+            filename=name_file
+        )
+    except plerr.PlotlyEmptyDataError:
+        logging.warning(u"No data for the plot. Skipped.")
+
+
 def plot_hdrh_lat_by_percentile(plot, input_data):
     """Generate the plot(s) with algorithm: plot_hdrh_lat_by_percentile
     specified in the specification file.
index 42f16e4..a715ecb 100644 (file)
@@ -917,7 +917,11 @@ def table_perf_trending_dash(table, input_data):
         if len(data_t) < 2:
             continue
 
-        classification_lst, avgs, _ = classify_anomalies(data_t)
+        try:
+            classification_lst, avgs, _ = classify_anomalies(data_t)
+        except ValueError as err:
+            logging.info(f"{err} Skipping")
+            return
 
         win_size = min(len(data_t), table[u"window"])
         long_win_size = min(len(data_t), table[u"long-trend-window"])
@@ -1341,6 +1345,8 @@ def table_last_failed_tests(table, input_data):
             build = str(build)
             try:
                 version = input_data.metadata(job, build).get(u"version", u"")
+                duration = \
+                    input_data.metadata(job, build).get(u"elapsedtime", u"")
             except KeyError:
                 logging.error(f"Data for {job}: {build} is not present.")
                 return
@@ -1359,15 +1365,16 @@ def table_last_failed_tests(table, input_data):
                     continue
                 nic = groups.group(0)
                 failed_tests.append(f"{nic}-{tst_data[u'name']}")
-            tbl_list.append(str(passed))
-            tbl_list.append(str(failed))
+            tbl_list.append(passed)
+            tbl_list.append(failed)
+            tbl_list.append(duration)
             tbl_list.extend(failed_tests)
 
     file_name = f"{table[u'output-file']}{table[u'output-file-ext']}"
     logging.info(f"    Writing file: {file_name}")
     with open(file_name, u"wt") as file_handler:
         for test in tbl_list:
-            file_handler.write(test + u'\n')
+            file_handler.write(f"{test}\n")
 
 
 def table_failed_tests(table, input_data):
index 00c2380..67c3636 100644 (file)
@@ -362,7 +362,6 @@ class ExecutionChecker(ResultVisitor):
         # Dictionary defining the methods used to parse different types of
         # messages
         self.parse_msg = {
-            u"timestamp": self._get_timestamp,
             u"vpp-version": self._get_vpp_version,
             u"dpdk-version": self._get_dpdk_version,
             u"teardown-papi-history": self._get_papi_history,
@@ -614,18 +613,6 @@ class ExecutionChecker(ResultVisitor):
             finally:
                 self._msg_type = None
 
-    def _get_timestamp(self, msg):
-        """Called when extraction of timestamp is required.
-
-        :param msg: Message to process.
-        :type msg: Message
-        :returns: Nothing.
-        """
-
-        self._timestamp = msg.timestamp[:14]
-        self._data[u"metadata"][u"generated"] = self._timestamp
-        self._msg_type = None
-
     def _get_papi_history(self, msg):
         """Called when extraction of PAPI command history is required.
 
@@ -1355,9 +1342,6 @@ class ExecutionChecker(ResultVisitor):
         elif setup_kw.name.count(u"Install Dpdk Framework On All Duts") and \
                 not self._version:
             self._msg_type = u"dpdk-version"
-        elif setup_kw.name.count(u"Set Global Variable") \
-                and not self._timestamp:
-            self._msg_type = u"timestamp"
         elif setup_kw.name.count(u"Setup Framework") and not self._testbed:
             self._msg_type = u"testbed"
         else:
@@ -1544,6 +1528,15 @@ class InputData:
         )
         result.visit(checker)
 
+        checker.data[u"metadata"][u"tests_total"] = \
+            result.statistics.total.all.total
+        checker.data[u"metadata"][u"tests_passed"] = \
+            result.statistics.total.all.passed
+        checker.data[u"metadata"][u"tests_failed"] = \
+            result.statistics.total.all.failed
+        checker.data[u"metadata"][u"elapsedtime"] = result.suite.elapsedtime
+        checker.data[u"metadata"][u"generated"] = result.suite.endtime[:14]
+
         return checker.data
 
     def _download_and_parse_build(self, job, build, repeat, pid=10000):
index 68ec170..a640401 100644 (file)
@@ -1,7 +1,145 @@
 ################################################################################
-###                               T A B L E S                                ###
+###                                P L O T S                                 ###
 ################################################################################
 
+- type: "plot"
+  title: "Statistics: 3n-skx mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-3n-skx-mrr"
+  data: "plot-performance-trending-vpp-3n-skx"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: 3n-skx ndrpdr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-3n-skx-ndrpdr"
+  data: "plot-ndrpdr-comparison-3n-skx"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: DPDK 3n-skx mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-dpdk-3n-skx-mrr"
+  data: "plot-performance-trending-dpdk-3n-skx"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: 2n-skx mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-2n-skx-mrr"
+  data: "plot-performance-trending-vpp-2n-skx"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: 2n-skx ndrpdr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-2n-skx-ndrpdr"
+  data: "plot-ndrpdr-comparison-2n-skx"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: DPDK 2n-skx mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-dpdk-2n-skx-mrr"
+  data: "plot-performance-trending-dpdk-2n-skx"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: 2n-clx mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-2n-clx-mrr"
+  data: "plot-performance-trending-vpp-2n-clx"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: 2n-clx ndrpdr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-2n-clx-ndrpdr"
+  data: "plot-ndrpdr-comparison-2n-clx"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: DPDK 2n-clx mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-dpdk-2n-skx-mrr"
+  data: "plot-performance-trending-dpdk-2n-clx"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: 2n-zn2 mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-2n-zn2-mrr"
+  data: "plot-performance-trending-vpp-2n-zn2"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: DPDK 2n-zn2 mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-dpdk-2n-zn2-mrr"
+  data: "plot-performance-trending-dpdk-2n-zn2"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: 3n-tsh mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-3n-tsh-mrr"
+  data: "plot-performance-trending-vpp-3n-tsh"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: DPDK 3n-tsh mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-dpdk-3n-tsh-mrr"
+  data: "plot-performance-trending-dpdk-3n-tsh"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: 2n-tx2 mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-2n-tx2-mrr"
+  data: "plot-performance-trending-vpp-2n-tx2"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: DPDK 2n-tx2 mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-dpdk-2n-tx2-mrr"
+  data: "plot-performance-trending-dpdk-2n-tx2"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: 3n-dnv mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-3n-dnv-mrr"
+  data: "plot-performance-trending-vpp-3n-dnv"
+  layout:
+    layout: "plot-statistics"
+
+- type: "plot"
+  title: "Statistics: 2n-dnv mrr"
+  algorithm: "plot_statistics"
+  output-file: "{DIR[STATIC,VPP]}/stats-2n-dnv-mrr"
+  data: "plot-performance-trending-vpp-2n-dnv"
+  layout:
+    layout: "plot-statistics"
+
+################################################################################
+###                               T A B L E S                                ###
 ################################################################################
 
 # VPP NDRPDR weekly comparison 2n-skx-xxv710 2t1c ndr
     - reference: -2
       compare: -1
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) VPP 3n-skx"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) VPP 2n-skx"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) VPP 2n-clx"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) VPP 2n-zn2"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) VPP 3n-tsh"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) VPP 2n-tx2"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) VPP 3n-dnv"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) VPP 2n-dnv"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) VPP 3n-skx-ndrpdr"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) VPP 2n-skx-ndrpdr"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) VPP 2n-clx-ndrpdr"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) DPDK 3n-tsh"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) DPDK 2n-tx2"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) DPDK 3n-skx"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) DPDK 2n-skx"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "parent"
     - "status"
 
--
-  type: "table"
+- type: "table"
   title: "Last failed tests (last builds) DPDK 2n-clx"
   algorithm: "table_last_failed_tests"
   output-file-ext: ".txt"
     - "status"
 
 # 3n-skx
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t1c-3n-skx ndr"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 4
   long-trend-window: 12
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t1c-3n-skx pdr"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 4
   long-trend-window: 12
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t1c-3n-skx ndr"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-3n-skx-ndr.csv"
   test-type: "NDR"
   add-links: True
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t1c-3n-skx pdr"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-3n-skx-pdr.csv"
   add-links: True
 
 # 2n-skx
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t1c-2n-skx ndr"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 4
   long-trend-window: 12
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t1c-2n-skx pdr"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 4
   long-trend-window: 12
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t1c-2n-skx ndr"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-2n-skx-ndr.csv"
   test-type: "NDR"
   add-links: True
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t1c-2n-skx pdr"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-2n-skx-pdr.csv"
   add-links: True
 
 # 2n-clx
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t1c-2n-clx ndr"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t1c-2n-clx pdr"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t1c-2n-clx ndr"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-2n-clx-ndr.csv"
   test-type: "NDR"
   add-links: True
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t1c-2n-clx pdr"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-2n-clx-pdr.csv"
 
 ###############################################################################
 # 3n-skx
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t1c-3n-skx"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 4t2c-3n-skx"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 8t4c-3n-skx"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t1c-3n-skx"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-3n-skx.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-3n-skx.rst"
   testbed: "3n-skx"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 4t2c-3n-skx"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t2c-3n-skx.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t2c-3n-skx.rst"
   testbed: "3n-skx"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 8t4c-3n-skx"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-8t4c-3n-skx.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-8t4c-3n-skx.rst"
   testbed: "3n-skx"
 
--
-  type: "table"
+- type: "table"
   title: "Failed MRR tests 3n-skx"
   algorithm: "table_failed_tests"
   output-file-ext: ".csv"
     - "status"
   window: 7  # days
 
--
-  type: "table"
+- type: "table"
   title: "HTML Failed MRR tests 3n-skx"
   algorithm: "table_failed_tests_html"
   input-file: "{DIR[STATIC,VPP]}/failed-tests-3n-skx.csv"
   output-file: "{DIR[STATIC,VPP]}/failed-tests-3n-skx.rst"
   testbed: "3n-skx"
 
--
-  type: "table"
+- type: "table"
   title: "Failed NDRPDR tests 3n-skx"
   algorithm: "table_failed_tests"
   output-file-ext: ".csv"
     - "status"
   window: 30  # days
 
--
-  type: "table"
+- type: "table"
   title: "HTML Failed NDRPDR tests 3n-skx"
   algorithm: "table_failed_tests_html"
   input-file: "{DIR[STATIC,VPP]}/failed-tests-3n-skx-ndrpdr.csv"
 
 ################################################################################
 # 2n-skx
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t1c-2n-skx"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 4t2c-2n-skx"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 8t4c-2n-skx"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t1c-2n-skx"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-2n-skx.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-2n-skx.rst"
   testbed: "2n-skx"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 4t2c-2n-skx"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t2c-2n-skx.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t2c-2n-skx.rst"
   testbed: "2n-skx"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 8t4c-2n-skx"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-8t4c-2n-skx.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-8t4c-2n-skx.rst"
   testbed: "2n-skx"
 
--
-  type: "table"
+- type: "table"
   title: "Failed MRR tests 2n-skx"
   algorithm: "table_failed_tests"
   output-file-ext: ".csv"
     - "status"
   window: 7  # days
 
--
-  type: "table"
+- type: "table"
   title: "HTML Failed MRR tests 2n-skx"
   algorithm: "table_failed_tests_html"
   input-file: "{DIR[STATIC,VPP]}/failed-tests-2n-skx.csv"
   output-file: "{DIR[STATIC,VPP]}/failed-tests-2n-skx.rst"
   testbed: "2n-skx"
 
--
-  type: "table"
+- type: "table"
   title: "Failed NDRPDR tests 2n-skx"
   algorithm: "table_failed_tests"
   output-file-ext: ".csv"
     - "status"
   window: 30  # days
 
--
-  type: "table"
+- type: "table"
   title: "HTML Failed NDRPDR tests 2n-skx"
   algorithm: "table_failed_tests_html"
   input-file: "{DIR[STATIC,VPP]}/failed-tests-2n-skx-ndrpdr.csv"
 
 ################################################################################
 # 2n-clx
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t1c-2n-clx"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 4t2c-2n-clx"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 8t4c-2n-clx"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t1c-2n-clx"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-2n-clx.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-2n-clx.rst"
   testbed: "2n-clx"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 4t2c-2n-clx"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t2c-2n-clx.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t2c-2n-clx.rst"
   testbed: "2n-clx"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 8t4c-2n-clx"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-8t4c-2n-clx.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-8t4c-2n-clx.rst"
   testbed: "2n-clx"
 
--
-  type: "table"
+- type: "table"
   title: "Failed MRR tests 2n-clx"
   algorithm: "table_failed_tests"
   output-file-ext: ".csv"
     - "status"
   window: 7  # days
 
--
-  type: "table"
+- type: "table"
   title: "HTML Failed MRR tests 2n-clx"
   algorithm: "table_failed_tests_html"
   input-file: "{DIR[STATIC,VPP]}/failed-tests-2n-clx.csv"
   output-file: "{DIR[STATIC,VPP]}/failed-tests-2n-clx.rst"
   testbed: "2n-clx"
 
--
-  type: "table"
+- type: "table"
   title: "Failed NDRPDR tests 2n-clx"
   algorithm: "table_failed_tests"
   output-file-ext: ".csv"
     - "status"
   window: 30  # days
 
--
-  type: "table"
+- type: "table"
   title: "HTML Failed NDRPDR tests 2n-clx"
   algorithm: "table_failed_tests_html"
   input-file: "{DIR[STATIC,VPP]}/failed-tests-2n-clx-ndrpdr.csv"
 
 ################################################################################
 # 2n-zn2
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t1c-2n-zn2"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 4t2c-2n-zn2"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 8t4c-2n-zn2"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t1c-2n-zn2"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-2n-zn2.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t1c-2n-zn2.rst"
   testbed: "2n-zn2"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 4t2c-2n-zn2"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t2c-2n-zn2.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t2c-2n-zn2.rst"
   testbed: "2n-zn2"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 8t4c-2n-zn2"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-8t4c-2n-zn2.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-8t4c-2n-zn2.rst"
   testbed: "2n-zn2"
 
--
-  type: "table"
+- type: "table"
   title: "Failed MRR tests 2n-zn2"
   algorithm: "table_failed_tests"
   output-file-ext: ".csv"
     - "status"
   window: 7  # days
 
--
-  type: "table"
+- type: "table"
   title: "HTML Failed MRR tests 2n-zn2"
   algorithm: "table_failed_tests_html"
   input-file: "{DIR[STATIC,VPP]}/failed-tests-2n-zn2.csv"
 
 ################################################################################
 # 3n-tsh
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 1t1c-3n-tsh"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t2c-3n-tsh"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 4t4c-3n-tsh"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 1t1c-3n-tsh"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-1t1c-3n-tsh.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-1t1c-3n-tsh.rst"
   testbed: "3n-tsh"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t2c-3n-tsh"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t2c-3n-tsh.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t2c-3n-tsh.rst"
   testbed: "3n-tsh"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 4t4c-3n-tsh"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t4c-3n-tsh.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t4c-3n-tsh.rst"
   testbed: "3n-tsh"
 
--
-  type: "table"
+- type: "table"
   title: "Failed MRR tests 3n-tsh"
   algorithm: "table_failed_tests"
   output-file-ext: ".csv"
     - "status"
   window: 7  # days
 
--
-  type: "table"
+- type: "table"
   title: "HTML Failed MRR tests 3n-tsh"
   algorithm: "table_failed_tests_html"
   input-file: "{DIR[STATIC,VPP]}/failed-tests-3n-tsh.csv"
 
 ################################################################################
 # 2n-tx2
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 1t1c-2n-tx2"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t2c-2n-tx2"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 4t4c-2n-tx2"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 1t1c-2n-tx2"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-1t1c-2n-tx2.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-1t1c-2n-tx2.rst"
   testbed: "2n-tx2"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t2c-2n-tx2"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t2c-2n-tx2.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t2c-2n-tx2.rst"
   testbed: "2n-tx2"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 4t4c-2n-tx2"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t4c-2n-tx2.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t4c-2n-tx2.rst"
   testbed: "2n-tx2"
 
--
-  type: "table"
+- type: "table"
   title: "Failed MRR tests 2n-tx2"
   algorithm: "table_failed_tests"
   output-file-ext: ".csv"
     - "status"
   window: 7  # days
 
--
-  type: "table"
+- type: "table"
   title: "HTML Failed MRR tests 2n-tx2"
   algorithm: "table_failed_tests_html"
   input-file: "{DIR[STATIC,VPP]}/failed-tests-2n-tx2.csv"
 
 ################################################################################
 # 3n-dnv
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 1t1c-3n-dnv"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t2c-3n-dnv"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 4t4c-3n-dnv"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 1t1c-3n-dnv"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-1t1c-3n-dnv.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-1t1c-3n-dnv.rst"
   testbed: "3n-dnv"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t2c-3n-dnv"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t2c-3n-dnv.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t2c-3n-dnv.rst"
   testbed: "3n-dnv"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 4t4c-3n-dnv"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t4c-3n-dnv.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t4c-3n-dnv.rst"
   testbed: "3n-dnv"
 
--
-  type: "table"
+- type: "table"
   title: "Failed MRR tests 3n-dnv"
   algorithm: "table_failed_tests"
   output-file-ext: ".csv"
     - "status"
   window: 7  # days
 
--
-  type: "table"
+- type: "table"
   title: "HTML Failed MRR tests 3n-dnv"
   algorithm: "table_failed_tests_html"
   input-file: "{DIR[STATIC,VPP]}/failed-tests-3n-dnv.csv"
 
 ################################################################################
 # 2n-dnv
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 1t1c-2n-dnv"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 2t2c-2n-dnv"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "Performance trending dashboard 4t4c-2n-dnv"
   algorithm: "table_perf_trending_dash"
   output-file-ext: ".csv"
   window: 14
   long-trend-window: 180
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 1t1c-2n-dnv"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-1t1c-2n-dnv.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-1t1c-2n-dnv.rst"
   testbed: "2n-dnv"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 2t2c-2n-dnv"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t2c-2n-dnv.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-2t2c-2n-dnv.rst"
   testbed: "2n-dnv"
 
--
-  type: "table"
+- type: "table"
   title: "HTML performance trending dashboard 4t4c-2n-dnv"
   algorithm: "table_perf_trending_dash_html"
   input-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t4c-2n-dnv.csv"
   output-file: "{DIR[STATIC,VPP]}/performance-trending-dashboard-4t4c-2n-dnv.rst"
   testbed: "2n-dnv"
 
--
-  type: "table"
+- type: "table"
   title: "Failed MRR tests 2n-dnv"
   algorithm: "table_failed_tests"
   output-file-ext: ".csv"
     - "status"
   window: 7  # days
 
--
-  type: "table"
+- type: "table"
   title: "HTML Failed MRR tests 2n-dnv"
   algorithm: "table_failed_tests_html"
   input-file: "{DIR[STATIC,VPP]}/failed-tests-2n-dnv.csv"
 
 # Plots VPP Continuous Performance Trending and Analysis
 
--
-  type: "cpta"
+- type: "cpta"
   title: "Continuous Performance Trending and Analysis"
   output-file: "{DIR[STATIC,VPP]}"
 
index ccc4a39..72bd69a 100644 (file)
@@ -4,6 +4,74 @@
 
 - type: "layouts"
 
+  plot-statistics:
+    title: ""
+    titlefont:
+      size: 16
+    autosize: True
+    showlegend: True
+    width: 1100
+    height: 800
+    yaxis:
+      showticklabels: True
+      title: "Number of Passed / Failed Tests"
+      gridcolor: "rgb(238, 238, 238)"
+      linecolor: "rgb(238, 238, 238)"
+      showline: True
+      zeroline: False
+      tickcolor: "rgb(238, 238, 238)"
+      linewidth: 1
+      showgrid: True
+    xaxis:
+      title: 'Date [MMDD]'
+      type: "date"
+      autorange: True
+      fixedrange: False
+      showgrid: True
+      gridcolor: "rgb(238, 238, 238)"
+      showline: True
+      linecolor: "rgb(238, 238, 238)"
+      zeroline: False
+      linewidth: 1
+      showticklabels: True
+      tickcolor: "rgb(238, 238, 238)"
+      tickmode: "auto"
+      tickformat: "%m%d"
+      rangeselector:
+        buttons:
+        - count: 14
+          label: "2w"
+          step: "day"
+          stepmode: "backward"
+        - count: 1
+          label: "1m"
+          step: "month"
+          stepmode: "backward"
+        - count: 2
+          label: "2m"
+          step: "month"
+          stepmode: "backward"
+        - count: 3
+          label: "3m"
+          step: "month"
+          stepmode: "backward"
+        - step: "all"
+    margin:
+      r: 20
+      b: 5
+      t: 5
+      l: 70
+    legend:
+      orientation: "h"
+      xanchor: "center"
+      x: 0.5
+      bordercolor: "rgb(238, 238, 238)"
+    paper_bgcolor: "#fff"
+    plot_bgcolor: "#fff"
+    barmode: "stack"
+    hoverlabel:
+      namelength: -1
+
   plot-cpta:
     title: ""
     titlefont: