UTI: Simplify the 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
22
23 def _table_info(job_data: pd.DataFrame) -> dbc.Table:
24     """Generates table with info about the job.
25
26     :param job_data: Dataframe with information about the job.
27     :type job_data: pandas.DataFrame
28     :returns: Table with job info.
29     :rtype: dbc.Table
30     """
31     return dbc.Table.from_dataframe(
32         pd.DataFrame.from_dict(
33             {
34                 "Job": job_data["job"],
35                 "Last Build": job_data["build"],
36                 "Date": job_data["start"],
37                 "DUT": job_data["dut_type"],
38                 "DUT Version": job_data["dut_version"],
39                 "Hosts": ", ".join(job_data["hosts"].to_list()[0])
40             }
41         ),
42         bordered=True,
43         striped=True,
44         hover=True,
45         size="sm",
46         color="info"
47     )
48
49
50 def _table_failed(job_data: pd.DataFrame, failed: list) -> dbc.Table:
51     """Generates table with failed tests from the last run of the job.
52
53     :param job_data: Dataframe with information about the job.
54     :param failed: List of failed tests.
55     :type job_data: pandas.DataFrame
56     :type failed: list
57     :returns: Table with fialed tests.
58     :rtype: dbc.Table
59     """
60     return dbc.Table.from_dataframe(
61         pd.DataFrame.from_dict(
62             {
63                 (
64                     f"Last Failed Tests on "
65                     f"{job_data['start'].values[0]} ({len(failed)})"
66                 ): failed
67             }
68         ),
69         bordered=True,
70         striped=True,
71         hover=True,
72         size="sm",
73         color="danger"
74     )
75
76
77 def _table_gressions(itms: dict, color: str) -> dbc.Table:
78     """Generates table with regressions.
79
80     :param itms: Dictionary with items (regressions or progressions) and their
81         last occurence.
82     :param color: Color of the table.
83     :type regressions: dict
84     :type color: str
85     :returns: The table with regressions.
86     :rtype: dbc.Table
87     """
88     return dbc.Table.from_dataframe(
89         pd.DataFrame.from_dict(itms),
90         bordered=True,
91         striped=True,
92         hover=True,
93         size="sm",
94         color=color
95     )
96
97
98 def table_news(data: pd.DataFrame, job: str, period: int) -> list:
99     """Generates the tables with news:
100     1. Falied tests from the last run
101     2. Regressions and progressions calculated from the last C.NEWS_TIME_PERIOD
102        days.
103
104     :param data: Trending data with calculated annomalies to be displayed in the
105         tables.
106     :param job: The job name.
107     :param period: The time period (nr of days from now) taken into account.
108     :type data: pandas.DataFrame
109     :type job: str
110     :type period: int
111     :returns: List of tables.
112     :rtype: list
113     """
114
115     last_day = datetime.utcnow() - timedelta(days=period)
116     r_list = list()
117     job_data = data.loc[(data["job"] == job)]
118     r_list.append(_table_info(job_data))
119
120     failed = job_data["failed"].to_list()[0]
121     if failed:
122         r_list.append(_table_failed(job_data, failed))
123
124     title = f"Regressions in the last {period} days"
125     regressions = {title: list(), "Last Regression": list()}
126     for itm in job_data["regressions"].to_list()[0]:
127         if itm[1] < last_day:
128             break
129         regressions[title].append(itm[0])
130         regressions["Last Regression"].append(
131             itm[1].strftime('%Y-%m-%d %H:%M'))
132     if regressions["Last Regression"]:
133         r_list.append(_table_gressions(regressions, "warning"))
134
135     title = f"Progressions in the last {period} days"
136     progressions = {title: list(), "Last Progression": list()}
137     for itm in job_data["progressions"].to_list()[0]:
138         if itm[1] < last_day:
139             break
140         progressions[title].append(itm[0])
141         progressions["Last Progression"].append(
142             itm[1].strftime('%Y-%m-%d %H:%M'))
143     if progressions["Last Progression"]:
144         r_list.append(_table_gressions(progressions, "success"))
145
146     return r_list
147
148
149 def table_summary(data: pd.DataFrame, jobs: list, period: int) -> list:
150     """Generates summary (failed tests, regressions and progressions) from the
151     last week.
152
153     :param data: Trending data with calculated annomalies to be displayed in the
154         tables.
155     :param jobs: List of jobs.
156     :params period: The time period for the summary table.
157     :type data: pandas.DataFrame
158     :type job: str
159     :type period: int
160     :returns: List of tables.
161     :rtype: list
162     """
163
164     return [
165         dbc.Accordion(
166             children=[
167                 dbc.AccordionItem(
168                     title=job,
169                     children=table_news(data, job, period)
170                 ) for job in jobs
171             ],
172             class_name="gy-2 p-0",
173             start_collapsed=True,
174             always_open=True
175         )
176     ]