aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTibor Frank <tifrank@cisco.com>2018-03-26 16:34:51 +0200
committerTibor Frank <tifrank@cisco.com>2018-03-26 17:02:35 +0200
commitb50e90db2a781b2b1a5a63be5734a0f4e635b2b1 (patch)
tree37da3971a647152af1728683b219395bbde2ad8e
parentea23a533875c9f0a901a984585bc67b5d1457662 (diff)
Report: Fix packet_throughput_graphs/ip4
Change-Id: I3943d02dcca95ed31baaa104648589c42ef479a7 Signed-off-by: Tibor Frank <tifrank@cisco.com>
-rw-r--r--resources/tools/presentation/generator_tables.py20
-rw-r--r--resources/tools/presentation/specification.yaml12
-rw-r--r--resources/tools/presentation/utils.py138
3 files changed, 150 insertions, 20 deletions
diff --git a/resources/tools/presentation/generator_tables.py b/resources/tools/presentation/generator_tables.py
index 76254c86dd..a667fffb16 100644
--- a/resources/tools/presentation/generator_tables.py
+++ b/resources/tools/presentation/generator_tables.py
@@ -401,21 +401,17 @@ def table_performance_comparison(table, input_data):
for tst_name in tbl_dict.keys():
item = [tbl_dict[tst_name]["name"], ]
if tbl_dict[tst_name]["ref-data"]:
- item.append(round(mean(remove_outliers(
- tbl_dict[tst_name]["ref-data"],
- table["outlier-const"])) / 1000000, 2))
- item.append(round(stdev(remove_outliers(
- tbl_dict[tst_name]["ref-data"],
- table["outlier-const"])) / 1000000, 2))
+ data_t = remove_outliers(tbl_dict[tst_name]["ref-data"],
+ table["outlier-const"])
+ item.append(round(mean(data_t) / 1000000, 2))
+ item.append(round(stdev(data_t) / 1000000, 2))
else:
item.extend([None, None])
if tbl_dict[tst_name]["cmp-data"]:
- item.append(round(mean(remove_outliers(
- tbl_dict[tst_name]["cmp-data"],
- table["outlier-const"])) / 1000000, 2))
- item.append(round(stdev(remove_outliers(
- tbl_dict[tst_name]["cmp-data"],
- table["outlier-const"])) / 1000000, 2))
+ data_t = remove_outliers(tbl_dict[tst_name]["cmp-data"],
+ table["outlier-const"])
+ item.append(round(mean(data_t) / 1000000, 2))
+ item.append(round(stdev(data_t) / 1000000, 2))
else:
item.extend([None, None])
if item[1] is not None and item[3] is not None:
diff --git a/resources/tools/presentation/specification.yaml b/resources/tools/presentation/specification.yaml
index b8ee748aab..ddf53636ee 100644
--- a/resources/tools/presentation/specification.yaml
+++ b/resources/tools/presentation/specification.yaml
@@ -1597,7 +1597,7 @@
output-file: "{DIR[STATIC,VPP]}/64B-1t1c-ethip4-ip4-ndrdisc"
data:
"plot-vpp-throughput-latency"
- filter: "'64B' and ('BASE' or 'SCALE' or 'FEATURE') and 'NDRDISC' and '1T1C' and 'IP4FWD' and not 'IPSEC' and not 'VHOST'"
+ filter: "'64B' and ('BASE' or 'SCALE' or 'FEATURE') and 'NDRDISC' and '1T1C' and 'IP4FWD' and not 'ACL1' and not 'ACL10' and not '100_FLOWS' and not '100k_FLOWS' and not 'IPSEC' and not 'VHOST'"
parameters:
- "throughput"
- "parent"
@@ -1618,7 +1618,7 @@
output-file: "{DIR[STATIC,VPP]}/64B-2t2c-ethip4-ip4-ndrdisc"
data:
"plot-vpp-throughput-latency"
- filter: "'64B' and ('BASE' or 'SCALE' or 'FEATURE') and 'NDRDISC' and '2T2C' and 'IP4FWD' and not 'IPSEC' and not 'VHOST'"
+ filter: "'64B' and ('BASE' or 'SCALE' or 'FEATURE') and 'NDRDISC' and '2T2C' and 'IP4FWD' and not 'ACL1' and not 'ACL10' and not '100_FLOWS' and not '100k_FLOWS' and not 'IPSEC' and not 'VHOST'"
parameters:
- "throughput"
- "parent"
@@ -1639,7 +1639,7 @@
output-file: "{DIR[STATIC,VPP]}/64B-1t1c-ethip4-ip4-pdrdisc"
data:
"plot-vpp-throughput-latency"
- filter: "'64B' and ('BASE' or 'SCALE' or 'FEATURE') and 'PDRDISC' and not 'NDRDISC' and '1T1C' and 'IP4FWD' and not 'IPSEC' and not 'VHOST'"
+ filter: "'64B' and ('BASE' or 'SCALE' or 'FEATURE') and 'PDRDISC' and not 'NDRDISC' and '1T1C' and 'IP4FWD' and not 'ACL1' and not 'ACL10' and not '100_FLOWS' and not '100k_FLOWS' and not 'IPSEC' and not 'VHOST'"
parameters:
- "throughput"
- "parent"
@@ -1660,7 +1660,7 @@
output-file: "{DIR[STATIC,VPP]}/64B-2t2c-ethip4-ip4-pdrdisc"
data:
"plot-vpp-throughput-latency"
- filter: "'64B' and ('BASE' or 'SCALE' or 'FEATURE') and 'PDRDISC' and not 'NDRDISC' and '2T2C' and 'IP4FWD' and not 'IPSEC' and not 'VHOST'"
+ filter: "'64B' and ('BASE' or 'SCALE' or 'FEATURE') and 'PDRDISC' and not 'NDRDISC' and '2T2C' and 'IP4FWD' and not 'ACL1' and not 'ACL10' and not '100_FLOWS' and not '100k_FLOWS' and not 'IPSEC' and not 'VHOST'"
parameters:
- "throughput"
- "parent"
@@ -2700,7 +2700,7 @@
output-file: "{DIR[STATIC,VPP]}/64B-1t1c-ethip4-ip4-ndrdisc-lat50"
data:
"plot-vpp-throughput-latency"
- filter: "'64B' and ('BASE' or 'SCALE' or 'FEATURE') and 'NDRDISC' and '1T1C' and 'IP4FWD' and not 'IPSEC' and not 'VHOST'"
+ filter: "'64B' and ('BASE' or 'SCALE' or 'FEATURE') and 'NDRDISC' and '1T1C' and 'IP4FWD' and not 'ACL1' and not 'ACL10' and not '100_FLOWS' and not '100k_FLOWS' and not 'IPSEC' and not 'VHOST'"
parameters:
- "latency"
- "parent"
@@ -2719,7 +2719,7 @@
output-file: "{DIR[STATIC,VPP]}/64B-2t2c-ethip4-ip4-ndrdisc-lat50"
data:
"plot-vpp-throughput-latency"
- filter: "'64B' and ('BASE' or 'SCALE' or 'FEATURE') and 'NDRDISC' and '2T2C' and 'IP4FWD' and not 'IPSEC' and not 'VHOST'"
+ filter: "'64B' and ('BASE' or 'SCALE' or 'FEATURE') and 'NDRDISC' and '2T2C' and 'IP4FWD' and not 'ACL1' and not 'ACL10' and not '100_FLOWS' and not '100k_FLOWS' and not 'IPSEC' and not 'VHOST'"
parameters:
- "latency"
- "parent"
diff --git a/resources/tools/presentation/utils.py b/resources/tools/presentation/utils.py
index 7037404c27..8365bfad5c 100644
--- a/resources/tools/presentation/utils.py
+++ b/resources/tools/presentation/utils.py
@@ -14,12 +14,18 @@
"""General purpose utilities.
"""
+import subprocess
import numpy as np
+import pandas as pd
+import logging
-from os import walk
-from os.path import join
+from os import walk, makedirs, environ
+from os.path import join, isdir
+from shutil import copy, Error
from math import sqrt
+from errors import PresentationError
+
def mean(items):
"""Calculate mean value from the items.
@@ -85,6 +91,39 @@ def remove_outliers(input_data, outlier_const):
return result_lst
+def find_outliers(input_data, outlier_const=1.5):
+ """Go through the input data and generate two pandas series:
+ - input data without outliers
+ - outliers.
+ The function uses IQR to detect outliers.
+
+ :param input_data: Data to be examined for outliers.
+ :param outlier_const: Outlier constant.
+ :type input_data: pandas.Series
+ :type outlier_const: float
+ :returns: Tuple: input data with outliers removed; Outliers.
+ :rtype: tuple (trimmed_data, outliers)
+ """
+
+ upper_quartile = input_data.quantile(q=0.75)
+ lower_quartile = input_data.quantile(q=0.25)
+ iqr = (upper_quartile - lower_quartile) * outlier_const
+ low = lower_quartile - iqr
+ high = upper_quartile + iqr
+ trimmed_data = pd.Series()
+ outliers = pd.Series()
+ for item in input_data.items():
+ item_pd = pd.Series([item[1], ], index=[item[0], ])
+ if low <= item[1] <= high:
+ trimmed_data = trimmed_data.append(item_pd)
+ else:
+ trimmed_data = trimmed_data.append(pd.Series([np.nan, ],
+ index=[item[0], ]))
+ outliers = outliers.append(item_pd)
+
+ return trimmed_data, outliers
+
+
def get_files(path, extension=None, full_path=True):
"""Generates the list of files to process.
@@ -127,3 +166,98 @@ def get_rst_title_char(level):
return chars[level]
else:
return chars[-1]
+
+
+def execute_command(cmd):
+ """Execute the command in a subprocess and log the stdout and stderr.
+
+ :param cmd: Command to execute.
+ :type cmd: str
+ :returns: Return code of the executed command.
+ :rtype: int
+ """
+
+ env = environ.copy()
+ proc = subprocess.Popen(
+ [cmd],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ shell=True,
+ env=env)
+
+ stdout, stderr = proc.communicate()
+
+ logging.info(stdout)
+ logging.info(stderr)
+
+ if proc.returncode != 0:
+ logging.error(" Command execution failed.")
+ return proc.returncode, stdout, stderr
+
+
+def get_last_successful_build_number(jenkins_url, job_name):
+ """Get the number of the last successful build of the given job.
+
+ :param jenkins_url: Jenkins URL.
+ :param job_name: Job name.
+ :type jenkins_url: str
+ :type job_name: str
+ :returns: The build number as a string.
+ :rtype: str
+ """
+
+ url = "{}/{}/lastSuccessfulBuild/buildNumber".format(jenkins_url, job_name)
+ cmd = "wget -qO- {url}".format(url=url)
+
+ return execute_command(cmd)
+
+
+def get_last_completed_build_number(jenkins_url, job_name):
+ """Get the number of the last completed build of the given job.
+
+ :param jenkins_url: Jenkins URL.
+ :param job_name: Job name.
+ :type jenkins_url: str
+ :type job_name: str
+ :returns: The build number as a string.
+ :rtype: str
+ """
+
+ url = "{}/{}/lastCompletedBuild/buildNumber".format(jenkins_url, job_name)
+ cmd = "wget -qO- {url}".format(url=url)
+
+ return execute_command(cmd)
+
+
+def archive_input_data(spec):
+ """Archive the report.
+
+ :param spec: Specification read from the specification file.
+ :type spec: Specification
+ :raises PresentationError: If it is not possible to archive the input data.
+ """
+
+ logging.info(" Archiving the input data files ...")
+
+ if spec.is_debug:
+ extension = spec.debug["input-format"]
+ else:
+ extension = spec.input["file-format"]
+ data_files = get_files(spec.environment["paths"]["DIR[WORKING,DATA]"],
+ extension=extension)
+ dst = spec.environment["paths"]["DIR[STATIC,ARCH]"]
+ logging.info(" Destination: {0}".format(dst))
+
+ try:
+ if not isdir(dst):
+ makedirs(dst)
+
+ for data_file in data_files:
+ logging.info(" Copying the file: {0} ...".format(data_file))
+ copy(data_file, dst)
+
+ except (Error, OSError) as err:
+ raise PresentationError("Not possible to archive the input data.",
+ str(err))
+
+ logging.info(" Done.")