X-Git-Url: https://gerrit.fd.io/r/gitweb?p=csit.git;a=blobdiff_plain;f=resources%2Ftools%2Fdash%2Fapp%2Fpal%2Ftrending%2Fgraphs.py;fp=resources%2Ftools%2Fdash%2Fapp%2Fpal%2Ftrending%2Fgraphs.py;h=0000000000000000000000000000000000000000;hp=1eff4aa88981986156cc9ee7410a2728bb24f981;hb=d6a60b5043c6f7c3dfc45853feb68d0aca5a4a5f;hpb=d2ef7bc01df66f6a27f25d061db064cf4a463267 diff --git a/resources/tools/dash/app/pal/trending/graphs.py b/resources/tools/dash/app/pal/trending/graphs.py deleted file mode 100644 index 1eff4aa889..0000000000 --- a/resources/tools/dash/app/pal/trending/graphs.py +++ /dev/null @@ -1,408 +0,0 @@ -# Copyright (c) 2022 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -""" - -import plotly.graph_objects as go -import pandas as pd - -import hdrh.histogram -import hdrh.codec - -from datetime import datetime - -from ..utils.constants import Constants as C -from ..utils.utils import classify_anomalies, get_color - - -def _get_hdrh_latencies(row: pd.Series, name: str) -> dict: - """Get the HDRH latencies from the test data. - - :param row: A row fron the data frame with test data. - :param name: The test name to be displayed as the graph title. - :type row: pandas.Series - :type name: str - :returns: Dictionary with HDRH latencies. - :rtype: dict - """ - - latencies = {"name": name} - for key in C.LAT_HDRH: - try: - latencies[key] = row[key] - except KeyError: - return None - - return latencies - - -def select_trending_data(data: pd.DataFrame, itm:dict) -> pd.DataFrame: - """Select the data for graphs from the provided data frame. - - :param data: Data frame with data for graphs. - :param itm: Item (in this case job name) which data will be selected from - the input data frame. - :type data: pandas.DataFrame - :type itm: str - :returns: A data frame with selected data. - :rtype: pandas.DataFrame - """ - - phy = itm["phy"].split("-") - if len(phy) == 4: - topo, arch, nic, drv = phy - if drv == "dpdk": - drv = "" - else: - drv += "-" - drv = drv.replace("_", "-") - else: - return None - - core = str() if itm["dut"] == "trex" else f"{itm['core']}" - ttype = "ndrpdr" if itm["testtype"] in ("ndr", "pdr") else itm["testtype"] - dut_v100 = "none" if itm["dut"] == "trex" else itm["dut"] - dut_v101 = itm["dut"] - - df = data.loc[( - ( - ( - (data["version"] == "1.0.0") & - (data["dut_type"].str.lower() == dut_v100) - ) | - ( - (data["version"] == "1.0.1") & - (data["dut_type"].str.lower() == dut_v101) - ) - ) & - (data["test_type"] == ttype) & - (data["passed"] == True) - )] - df = df[df.job.str.endswith(f"{topo}-{arch}")] - df = df[df.test_id.str.contains( - f"^.*[.|-]{nic}.*{itm['framesize']}-{core}-{drv}{itm['test']}-{ttype}$", - regex=True - )].sort_values(by="start_time", ignore_index=True) - - return df - - -def _generate_trending_traces(ttype: str, name: str, df: pd.DataFrame, - color: str, norm_factor: float) -> list: - """Generate the trending traces for the trending graph. - - :param ttype: Test type (MRR, NDR, PDR). - :param name: The test name to be displayed as the graph title. - :param df: Data frame with test data. - :param color: The color of the trace (samples and trend line). - :param norm_factor: The factor used for normalization of the results to CPU - frequency set to Constants.NORM_FREQUENCY. - :type ttype: str - :type name: str - :type df: pandas.DataFrame - :type color: str - :type norm_factor: float - :returns: Traces (samples, trending line, anomalies) - :rtype: list - """ - - df = df.dropna(subset=[C.VALUE[ttype], ]) - if df.empty: - return list() - if df.empty: - return list() - - x_axis = df["start_time"].tolist() - if ttype == "pdr-lat": - y_data = [(itm / norm_factor) for itm in df[C.VALUE[ttype]].tolist()] - else: - y_data = [(itm * norm_factor) for itm in df[C.VALUE[ttype]].tolist()] - - anomalies, trend_avg, trend_stdev = classify_anomalies( - {k: v for k, v in zip(x_axis, y_data)} - ) - - hover = list() - customdata = list() - for idx, (_, row) in enumerate(df.iterrows()): - d_type = "trex" if row["dut_type"] == "none" else row["dut_type"] - hover_itm = ( - f"date: {row['start_time'].strftime('%Y-%m-%d %H:%M:%S')}
" - f" [{row[C.UNIT[ttype]]}]: {y_data[idx]:,.0f}
" - f"" - f"{d_type}-ref: {row['dut_version']}
" - f"csit-ref: {row['job']}/{row['build']}
" - f"hosts: {', '.join(row['hosts'])}" - ) - if ttype == "mrr": - stdev = ( - f"stdev [{row['result_receive_rate_rate_unit']}]: " - f"{row['result_receive_rate_rate_stdev']:,.0f}
" - ) - else: - stdev = "" - hover_itm = hover_itm.replace( - "", "latency" if ttype == "pdr-lat" else "average" - ).replace("", stdev) - hover.append(hover_itm) - if ttype == "pdr-lat": - customdata.append(_get_hdrh_latencies(row, name)) - - hover_trend = list() - for avg, stdev, (_, row) in zip(trend_avg, trend_stdev, df.iterrows()): - d_type = "trex" if row["dut_type"] == "none" else row["dut_type"] - hover_itm = ( - f"date: {row['start_time'].strftime('%Y-%m-%d %H:%M:%S')}
" - f"trend [pps]: {avg:,.0f}
" - f"stdev [pps]: {stdev:,.0f}
" - f"{d_type}-ref: {row['dut_version']}
" - f"csit-ref: {row['job']}/{row['build']}
" - f"hosts: {', '.join(row['hosts'])}" - ) - if ttype == "pdr-lat": - hover_itm = hover_itm.replace("[pps]", "[us]") - hover_trend.append(hover_itm) - - traces = [ - go.Scatter( # Samples - x=x_axis, - y=y_data, - name=name, - mode="markers", - marker={ - "size": 5, - "color": color, - "symbol": "circle", - }, - text=hover, - hoverinfo="text+name", - showlegend=True, - legendgroup=name, - customdata=customdata - ), - go.Scatter( # Trend line - x=x_axis, - y=trend_avg, - name=name, - mode="lines", - line={ - "shape": "linear", - "width": 1, - "color": color, - }, - text=hover_trend, - hoverinfo="text+name", - showlegend=False, - legendgroup=name, - ) - ] - - if anomalies: - anomaly_x = list() - anomaly_y = list() - anomaly_color = list() - hover = list() - for idx, anomaly in enumerate(anomalies): - if anomaly in ("regression", "progression"): - anomaly_x.append(x_axis[idx]) - anomaly_y.append(trend_avg[idx]) - anomaly_color.append(C.ANOMALY_COLOR[anomaly]) - hover_itm = ( - f"date: {x_axis[idx].strftime('%Y-%m-%d %H:%M:%S')}
" - f"trend [pps]: {trend_avg[idx]:,.0f}
" - f"classification: {anomaly}" - ) - if ttype == "pdr-lat": - hover_itm = hover_itm.replace("[pps]", "[us]") - hover.append(hover_itm) - anomaly_color.extend([0.0, 0.5, 1.0]) - traces.append( - go.Scatter( - x=anomaly_x, - y=anomaly_y, - mode="markers", - text=hover, - hoverinfo="text+name", - showlegend=False, - legendgroup=name, - name=name, - marker={ - "size": 15, - "symbol": "circle-open", - "color": anomaly_color, - "colorscale": C.COLORSCALE_LAT \ - if ttype == "pdr-lat" else C.COLORSCALE_TPUT, - "showscale": True, - "line": { - "width": 2 - }, - "colorbar": { - "y": 0.5, - "len": 0.8, - "title": "Circles Marking Data Classification", - "titleside": "right", - "tickmode": "array", - "tickvals": [0.167, 0.500, 0.833], - "ticktext": C.TICK_TEXT_LAT \ - if ttype == "pdr-lat" else C.TICK_TEXT_TPUT, - "ticks": "", - "ticklen": 0, - "tickangle": -90, - "thickness": 10 - } - } - ) - ) - - return traces - - -def graph_trending(data: pd.DataFrame, sel:dict, layout: dict, - normalize: bool) -> tuple: - """Generate the trending graph(s) - MRR, NDR, PDR and for PDR also Latences - (result_latency_forward_pdr_50_avg). - - :param data: Data frame with test results. - :param sel: Selected tests. - :param layout: Layout of plot.ly graph. - :param normalize: If True, the data is normalized to CPU frquency - Constants.NORM_FREQUENCY. - :type data: pandas.DataFrame - :type sel: dict - :type layout: dict - :type normalize: bool - :returns: Trending graph(s) - :rtype: tuple(plotly.graph_objects.Figure, plotly.graph_objects.Figure) - """ - - if not sel: - return None, None - - fig_tput = None - fig_lat = None - for idx, itm in enumerate(sel): - - df = select_trending_data(data, itm) - if df is None or df.empty: - continue - - name = "-".join((itm["dut"], itm["phy"], itm["framesize"], itm["core"], - itm["test"], itm["testtype"], )) - if normalize: - phy = itm["phy"].split("-") - topo_arch = f"{phy[0]}-{phy[1]}" if len(phy) == 4 else str() - norm_factor = (C.NORM_FREQUENCY / C.FREQUENCY[topo_arch]) \ - if topo_arch else 1.0 - else: - norm_factor = 1.0 - traces = _generate_trending_traces( - itm["testtype"], name, df, get_color(idx), norm_factor - ) - if traces: - if not fig_tput: - fig_tput = go.Figure() - fig_tput.add_traces(traces) - - if itm["testtype"] == "pdr": - traces = _generate_trending_traces( - "pdr-lat", name, df, get_color(idx), norm_factor - ) - if traces: - if not fig_lat: - fig_lat = go.Figure() - fig_lat.add_traces(traces) - - if fig_tput: - fig_tput.update_layout(layout.get("plot-trending-tput", dict())) - if fig_lat: - fig_lat.update_layout(layout.get("plot-trending-lat", dict())) - - return fig_tput, fig_lat - - -def graph_hdrh_latency(data: dict, layout: dict) -> go.Figure: - """Generate HDR Latency histogram graphs. - - :param data: HDRH data. - :param layout: Layout of plot.ly graph. - :type data: dict - :type layout: dict - :returns: HDR latency Histogram. - :rtype: plotly.graph_objects.Figure - """ - - fig = None - - traces = list() - for idx, (lat_name, lat_hdrh) in enumerate(data.items()): - try: - decoded = hdrh.histogram.HdrHistogram.decode(lat_hdrh) - except (hdrh.codec.HdrLengthException, TypeError) as err: - continue - previous_x = 0.0 - prev_perc = 0.0 - xaxis = list() - yaxis = list() - hovertext = list() - for item in decoded.get_recorded_iterator(): - # The real value is "percentile". - # For 100%, we cut that down to "x_perc" to avoid - # infinity. - percentile = item.percentile_level_iterated_to - x_perc = min(percentile, C.PERCENTILE_MAX) - xaxis.append(previous_x) - yaxis.append(item.value_iterated_to) - hovertext.append( - f"{C.GRAPH_LAT_HDRH_DESC[lat_name]}
" - f"Direction: {('W-E', 'E-W')[idx % 2]}
" - f"Percentile: {prev_perc:.5f}-{percentile:.5f}%
" - f"Latency: {item.value_iterated_to}uSec" - ) - next_x = 100.0 / (100.0 - x_perc) - xaxis.append(next_x) - yaxis.append(item.value_iterated_to) - hovertext.append( - f"{C.GRAPH_LAT_HDRH_DESC[lat_name]}
" - f"Direction: {('W-E', 'E-W')[idx % 2]}
" - f"Percentile: {prev_perc:.5f}-{percentile:.5f}%
" - f"Latency: {item.value_iterated_to}uSec" - ) - previous_x = next_x - prev_perc = percentile - - traces.append( - go.Scatter( - x=xaxis, - y=yaxis, - name=C.GRAPH_LAT_HDRH_DESC[lat_name], - mode="lines", - legendgroup=C.GRAPH_LAT_HDRH_DESC[lat_name], - showlegend=bool(idx % 2), - line=dict( - color=get_color(int(idx/2)), - dash="solid", - width=1 if idx % 2 else 2 - ), - hovertext=hovertext, - hoverinfo="text" - ) - ) - if traces: - fig = go.Figure() - fig.add_traces(traces) - layout_hdrh = layout.get("plot-hdrh-latency", None) - if lat_hdrh: - fig.update_layout(layout_hdrh) - - return fig