3 # Copyright 2020 Orange, Ltd.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
23 from dataclasses import dataclass
29 from packaging.version import Version
31 from jinja2 import ( # pylint: disable=import-error
40 LOGGER = logging.getLogger("onap-versions-status-reporting")
41 LOGGER.setLevel(LOG_LEVEL)
43 REPORTING_FILE = "/var/lib/xtesting/results/versions_reporting.html"
44 # REPORTING_FILE = "/tmp/versions_reporting.html"
45 RESULT_FILE = "/tmp/versions.json"
46 RECOMMENDED_VERSIONS_FILE = "/tmp/recommended_versions.yaml"
47 WAIVER_LIST_FILE = "/tmp/versions_xfail.txt"
52 """Test results retrieved from xtesting."""
73 nb_occurences: int = 0
76 class OnapVersionsReporting:
77 """Build html summary page."""
79 def __init__(self, result_file) -> None:
80 """Initialization of the report."""
81 version = os.getenv("ONAP_VERSION", "master")
82 base_url = "https://git.onap.org/integration/seccom/plain"
83 if pathlib.Path(WAIVER_LIST_FILE).is_file():
84 self._waiver_file = pathlib.Path(WAIVER_LIST_FILE)
86 self._waiver_file = wget.download(
87 base_url + "/waivers/versions/versions_xfail.txt?h=" + version,
90 if pathlib.Path(RECOMMENDED_VERSIONS_FILE).is_file():
91 self._recommended_versions_file = pathlib.Path(RECOMMENDED_VERSIONS_FILE)
93 self._recommended_versions_file = wget.download(
94 base_url + "/recommended_versions.yaml?h=" + version,
95 out=RECOMMENDED_VERSIONS_FILE,
98 def get_versions_scan_results(self, result_file, waiver_list):
99 """Get all the versions from the scan."""
101 # Get the recommended version list for java and python
102 min_java_version = self.get_recommended_version(
103 RECOMMENDED_VERSIONS_FILE, "java11"
105 min_python_version = self.get_recommended_version(
106 RECOMMENDED_VERSIONS_FILE, "python3"
109 LOGGER.info("Min Java recommended version: %s", min_java_version)
110 LOGGER.info("Min Python recommended version: %s", min_python_version)
112 with open(result_file) as json_file:
113 data = json.load(json_file)
114 LOGGER.info("Number of pods: %s", len(data))
115 for component in data:
116 if component["container"] not in waiver_list:
119 pod_name=component["pod"],
120 container=component["container"],
121 image=component["extra"]["image"],
122 python_version=component["versions"]["python"],
123 java_version=component["versions"]["java"],
124 python_status=self.get_version_status(
125 component["versions"]["python"], min_python_version[0]
127 java_status=self.get_version_status(
128 component["versions"]["java"], min_java_version[0]
132 LOGGER.info("Nb of pods (after waiver filtering) %s", len(testresult))
136 def get_version_status(versions, min_version):
137 """Based on the min version set the status of the component version."""
139 # 0: only recommended version found
140 # 1: recommended version found but not alone
141 # 2: recommended version not found but not far
142 # 3: recommended version not found but not far but not alone
143 # 4: recommended version not found
144 # we assume that versions are given accordign to usual java way
146 LOGGER.debug("Version = %s", versions)
147 LOGGER.debug("Min Version = %s", min_version)
148 nb_versions_found = len(versions)
150 LOGGER.debug("Nb versions found :%s", nb_versions_found)
151 # if no version found retrieved -1
152 if nb_versions_found > 0:
153 for version in versions:
154 clean_version = Version(version.replace("_", "."))
155 min_version_ok = str(min_version)
157 if clean_version >= Version(min_version_ok):
158 if nb_versions_found < 2:
162 elif clean_version.major >= Version(min_version_ok).major:
163 if nb_versions_found < 2:
169 LOGGER.debug("Version status code = %s", status_code)
173 def get_recommended_version(recommended_versions_file, component):
174 """Retrieve data from the json file."""
175 with open(recommended_versions_file) as stream:
176 data = yaml.safe_load(stream)
178 recommended_version = data[component]["recommended_versions"]
180 recommended_version = None
181 return recommended_version
184 def get_waiver_list(waiver_file_path):
185 """Get the waiver list."""
186 pods_to_be_excluded = []
187 with open(waiver_file_path) as waiver_list:
188 for line in waiver_list:
189 line = line.strip("\n")
190 line = line.strip("\t")
191 if not line.startswith("#"):
192 pods_to_be_excluded.append(line)
193 return pods_to_be_excluded
196 def get_score(component_type, scan_res):
197 # Look at the java and python results
198 # 0 = recommended version
199 # 1 = acceptable version
204 if component_type == "java":
205 if res.java_status >= 0:
207 if res.java_status < 2:
208 nb_good_versions += 1
209 elif component_type == "python":
210 if res.python_status >= 0:
212 if res.python_status < 2:
213 nb_good_versions += 1
215 return round(nb_good_versions * 100 / nb_results, 1)
216 except ZeroDivisionError:
217 LOGGER.error("Impossible to calculate the success rate")
220 def generate_reporting(self, result_file):
221 """Generate HTML reporting page."""
222 LOGGER.info("Generate versions HTML report.")
224 # Get the waiver list
225 waiver_list = self.get_waiver_list(self._waiver_file)
226 LOGGER.info("Waiver list: %s", waiver_list)
228 # Get the Versions results
229 scan_res = self.get_versions_scan_results(result_file, waiver_list)
231 LOGGER.info("scan_res: %s", scan_res)
234 status_res = {"java": 0, "python": 0}
235 for component_type in "java", "python":
236 status_res[component_type] = self.get_score(component_type, scan_res)
238 LOGGER.info("status_res: %s", status_res)
240 # Calculate the average score
241 numbers = [status_res[key] for key in status_res]
242 mean_ = statistics.mean(numbers)
244 # Create reporting page
245 jinja_env = Environment(
246 autoescape=select_autoescape(["html"]),
247 loader=PackageLoader("onap_check_versions"),
250 "title": "ONAP Integration versions reporting",
251 "success_rate": status_res,
254 jinja_env.get_template("versions.html.j2").stream(
255 info=page_info, data=scan_res
256 ).dump("{}".format(REPORTING_FILE))
261 if __name__ == "__main__":
262 test = OnapVersionsReporting(
263 RESULT_FILE, WAIVER_LIST_FILE, RECOMMENDED_VERSIONS_FILE
265 test.generate_reporting(RESULT_FILE)