UTI: Add Summary to News
[csit.git] / resources / tools / dash / app / pal / news / tables.py
1 # Copyright (c) 2022 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 """The tables with news.
15 """
16
17 import pandas as pd
18 import dash_bootstrap_components as dbc
19
20 from datetime import datetime, timedelta
21 from dash import html
22
23 from ..utils.constants import Constants as C
24
25
26 def _table_info(job_data: pd.DataFrame) -> dbc.Table:
27     """Generates table with info about the job.
28
29     :param job_data: Dataframe with information about the job.
30     :type job_data: pandas.DataFrame
31     :returns: Table with job info.
32     :rtype: dbc.Table
33     """
34     return dbc.Table.from_dataframe(
35         pd.DataFrame.from_dict(
36             {
37                 "Job": job_data["job"],
38                 "Last Build": job_data["build"],
39                 "Date": job_data["start"],
40                 "DUT": job_data["dut_type"],
41                 "DUT Version": job_data["dut_version"],
42                 "Hosts": ", ".join(job_data["hosts"].to_list()[0])
43             }
44         ),
45         bordered=True,
46         striped=True,
47         hover=True,
48         size="sm",
49         color="info"
50     )
51
52
53 def _table_failed(job_data: pd.DataFrame, failed: list) -> dbc.Table:
54     """Generates table with failed tests from the last run of the job.
55
56     :param job_data: Dataframe with information about the job.
57     :param failed: List of failed tests.
58     :type job_data: pandas.DataFrame
59     :type failed: list
60     :returns: Table with fialed tests.
61     :rtype: dbc.Table
62     """
63     return dbc.Table.from_dataframe(
64         pd.DataFrame.from_dict(
65             {
66                 (
67                     f"Last Failed Tests on "
68                     f"{job_data['start'].values[0]} ({len(failed)})"
69                 ): failed
70             }
71         ),
72         bordered=True,
73         striped=True,
74         hover=True,
75         size="sm",
76         color="danger"
77     )
78
79
80 def _table_gressions(itms: dict, color: str) -> dbc.Table:
81     """Generates table with regressions.
82
83     :param itms: Dictionary with items (regressions or progressions) and their
84         last occurence.
85     :param color: Color of the table.
86     :type regressions: dict
87     :type color: str
88     :returns: The table with regressions.
89     :rtype: dbc.Table
90     """
91     return dbc.Table.from_dataframe(
92         pd.DataFrame.from_dict(itms),
93         bordered=True,
94         striped=True,
95         hover=True,
96         size="sm",
97         color=color
98     )
99
100
101 def table_news(data: pd.DataFrame, job: str, period: int) -> list:
102     """Generates the tables with news:
103     1. Falied tests from the last run
104     2. Regressions and progressions calculated from the last C.NEWS_TIME_PERIOD
105        days.
106
107     :param data: Trending data with calculated annomalies to be displayed in the
108         tables.
109     :param job: The job name.
110     :param period: The time period (nr of days from now) taken into account.
111     :type data: pandas.DataFrame
112     :type job: str
113     :type period: int
114     :returns: List of tables.
115     :rtype: list
116     """
117
118     last_day = datetime.utcnow() - timedelta(days=period)
119     r_list = list()
120     job_data = data.loc[(data["job"] == job)]
121     r_list.append(_table_info(job_data))
122
123     failed = job_data["failed"].to_list()[0]
124     if failed:
125         r_list.append(_table_failed(job_data, failed))
126
127     title = f"Regressions in the last {period} days"
128     regressions = {title: list(), "Last Regression": list()}
129     for itm in job_data["regressions"].to_list()[0]:
130         if itm[1] < last_day:
131             break
132         regressions[title].append(itm[0])
133         regressions["Last Regression"].append(
134             itm[1].strftime('%Y-%m-%d %H:%M'))
135     if regressions["Last Regression"]:
136         r_list.append(_table_gressions(regressions, "warning"))
137
138     title = f"Progressions in the last {period} days"
139     progressions = {title: list(), "Last Progression": list()}
140     for itm in job_data["progressions"].to_list()[0]:
141         if itm[1] < last_day:
142             break
143         progressions[title].append(itm[0])
144         progressions["Last Progression"].append(
145             itm[1].strftime('%Y-%m-%d %H:%M'))
146     if progressions["Last Progression"]:
147         r_list.append(_table_gressions(progressions, "success"))
148
149     return r_list
150
151
152 def table_summary(data: pd.DataFrame, jobs: list) -> list:
153     """Generates summary (failed tests, regressions and progressions) from the
154     last week.
155
156     :param data: Trending data with calculated annomalies to be displayed in the
157         tables.
158     :param jobs: List of jobs.
159     :type data: pandas.DataFrame
160     :type job: str
161     :returns: List of tables.
162     :rtype: list
163     """
164
165     r_list = list()
166     for job in jobs:
167         r_list.extend(table_news(data, job, C.NEWS_SUMMARY_PERIOD))
168         r_list.append(html.Div(html.P(" ")))
169
170     return r_list