Merge "Doc: Release notes for Fraser"
[vswitchperf.git] / tools / opnfvdashboard / opnfvdashboard.py
1 """
2 vsperf2dashboard
3 """
4 # Copyright 2015-2017 Intel Corporation.
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 #   http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17
18 import os
19 import csv
20 import copy
21 import logging
22 from datetime import datetime as dt
23 import requests
24
25 _DETAILS = {"64": '', "128": '', "512": '', "1024": '', "1518": ''}
26
27 def results2opnfv_dashboard(tc_names, results_path, int_data):
28     """
29     the method open the csv file with results and calls json encoder
30     """
31     testcases = os.listdir(results_path)
32     for test in testcases:
33         if not ".csv" in test:
34             continue
35         resfile = results_path + '/' + test
36         with open(resfile, 'r') as in_file:
37             reader = csv.DictReader(in_file)
38             tc_data = _prepare_results(reader, int_data)
39             _push_results(tc_data)
40             tc_names.remove(tc_data['id'])
41
42     # report TCs without results as FAIL
43     if tc_names:
44         tc_fail = copy.deepcopy(int_data)
45         tc_fail['start_time'] = dt.now().strftime('%Y-%m-%d %H:%M:%S')
46         tc_fail['stop_time'] = tc_fail['start_time']
47         tc_fail['criteria'] = 'FAIL'
48         tc_fail['version'] = 'N/A'
49         tc_fail['details'] = copy.deepcopy(_DETAILS)
50         for tc_name in tc_names:
51             tc_fail['dashboard_id'] = "{}_{}".format(tc_name, tc_fail['vswitch'])
52             _push_results(tc_fail)
53
54 def _prepare_results(reader, int_data):
55     """
56     the method prepares dashboard details for passed testcases
57     """
58     version_vswitch = ""
59     version_dpdk = ""
60     allowed_pkt = ["64", "128", "512", "1024", "1518"]
61     vswitch = None
62     details = copy.deepcopy(_DETAILS)
63     tc_data = copy.deepcopy(int_data)
64     tc_data['criteria'] = 'PASS'
65
66     for row_reader in reader:
67         if allowed_pkt.count(row_reader['packet_size']) == 0:
68             logging.error("The framesize is not supported in opnfv dashboard")
69             continue
70
71         # test execution time includes all frame sizes, so start & stop time
72         # is the same (repeated) for every framesize in CSV file
73         if not 'test_start' in tc_data:
74             tc_data['start_time'] = row_reader['start_time']
75             tc_data['stop_time'] = row_reader['stop_time']
76             tc_data['id'] = row_reader['id']
77             # CI job executes/reports TCs per vswitch type
78             vswitch = row_reader['vswitch']
79
80         tc_data['dashboard_id'] = "{}_{}".format(row_reader['id'], row_reader['vswitch'].lower())
81         if "back2back" in row_reader['id']:
82             # 0 B2B frames is quite common, so we can't mark such TC as FAIL
83             details[row_reader['packet_size']] = row_reader['b2b_frames']
84         else:
85             details[row_reader['packet_size']] = row_reader['throughput_rx_fps']
86             # 0 PPS is definitelly a failure
87             if float(row_reader['throughput_rx_fps']) == 0:
88                 tc_data['criteria'] = 'FAIL'
89
90     # Create version field
91     with open(tc_data['pkg_list'], 'r') as pkg_file:
92         for line in pkg_file:
93             if "OVS_TAG" in line and vswitch.startswith('Ovs'):
94                 version_vswitch = line.replace(' ', '')
95                 version_vswitch = "OVS " + version_vswitch.replace('OVS_TAG?=', '')
96             if "VPP_TAG" in line and vswitch.startswith('Vpp'):
97                 version_vswitch = line.replace(' ', '')
98                 version_vswitch = "VPP " + version_vswitch.replace('VPP_TAG?=', '')
99             if "DPDK_TAG" in line:
100                 # DPDK_TAG is not used by VPP, it downloads its onw DPDK version
101                 if vswitch == "OvsDpdkVhost":
102                     version_dpdk = line.replace(' ', '')
103                     version_dpdk = " DPDK {}".format(
104                         version_dpdk.replace('DPDK_TAG?=', ''))
105
106     tc_data['details'] = details
107     tc_data['version'] = version_vswitch.replace('\n', '') + version_dpdk.replace('\n', '')
108
109     return tc_data
110
111 def _push_results(int_data):
112     """
113     the method sends testcase details into dashboard database
114     """
115     url = int_data['db_url'] + "/results"
116
117     # Build body
118     body = {"project_name": "vsperf",
119             "scenario": "vsperf",
120             "start_date": int_data['start_time'],
121             "stop_date": int_data['stop_time'],
122             "case_name": int_data['dashboard_id'],
123             "pod_name": int_data['pod'],
124             "installer": int_data['installer'],
125             "version": int_data['version'],
126             "build_tag": int_data['build_tag'],
127             "criteria": int_data['criteria'],
128             "details": int_data['details']}
129
130     my_data = requests.post(url, json=body)
131     logging.info("Results for %s sent to opnfv, http response: %s", int_data['dashboard_id'], my_data)
132     logging.debug("opnfv url: %s", int_data['db_url'])
133     logging.debug("the body sent to opnfv")
134     logging.debug(body)