aboutsummaryrefslogtreecommitdiffstats
path: root/resources/tools/presentation/utils.py
diff options
context:
space:
mode:
authorTibor Frank <tifrank@cisco.com>2018-03-01 14:52:47 +0100
committerTibor Frank <tifrank@cisco.com>2018-03-21 15:43:10 +0000
commitefdcf6470f6e15dcc918c70e5a61d10e10653f1e (patch)
treeb2d5a5a2163b56d12f300c06119e925377674187 /resources/tools/presentation/utils.py
parent70068307d35abcd40abbcd9275bcb836d2cdbae6 (diff)
CSIT-913: Continuous Trending, Analysis and Change Detection
- CSIT-915: LLD - CSIT-917: Functions to evaluate the results according to the PASS / FAIL criteria - CSIT-918: Sphinx configuration - CSIT-948: Statistical functions - CSIT-949: Data models for trending plots - CSIT-950: Code trending plots - CSIT-951: Static content - CSIT-984: PAL Specification file - CSIT-996: Download data from nexus Change-Id: Icb9305945bb0f142135bb177cb8781ba0096280e Signed-off-by: Tibor Frank <tifrank@cisco.com>
Diffstat (limited to 'resources/tools/presentation/utils.py')
-rw-r--r--resources/tools/presentation/utils.py125
1 files changed, 108 insertions, 17 deletions
diff --git a/resources/tools/presentation/utils.py b/resources/tools/presentation/utils.py
index 7037404c27..966d7f558b 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.
@@ -62,27 +68,37 @@ def relative_change(nr1, nr2):
return float(((nr2 - nr1) / nr1) * 100)
-def remove_outliers(input_data, outlier_const):
- """
+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 from which the outliers will be removed.
+ :param input_data: Data to be examined for outliers.
:param outlier_const: Outlier constant.
- :type input_data: list
+ :type input_data: pandas.Series
:type outlier_const: float
- :returns: The input list without outliers.
- :rtype: list
+ :returns: Tuple: input data with outliers removed; Outliers.
+ :rtype: tuple (trimmed_data, outliers)
"""
- data = np.array(input_data)
- upper_quartile = np.percentile(data, 75)
- lower_quartile = np.percentile(data, 25)
+ upper_quartile = input_data.quantile(q=0.75)
+ lower_quartile = input_data.quantile(q=0.25)
iqr = (upper_quartile - lower_quartile) * outlier_const
- quartile_set = (lower_quartile - iqr, upper_quartile + iqr)
- result_lst = list()
- for y in data.tolist():
- if quartile_set[0] <= y <= quartile_set[1]:
- result_lst.append(y)
- return result_lst
+ 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):
@@ -127,3 +143,78 @@ 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_build_number(jenkins_url, job_name):
+ """
+
+ :param jenkins_url:
+ :param job_name:
+ :return:
+ """
+
+ url = "{}/{}/lastSuccessfulBuild/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.")