aboutsummaryrefslogtreecommitdiffstats
path: root/tools/opnfvdashboard/opnfvdashboard.py
blob: a77a9c3a61b03464923200c04d09a2c479308c35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
"""
vsperf2dashboard
"""
# Copyright 2015-2017 Intel Corporation.
#
# 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 os
import csv
import copy
import logging
from datetime import datetime as dt
import requests

_DETAILS = {"64": '', "128": '', "512": '', "1024": '', "1518": ''}

def results2opnfv_dashboard(tc_names, results_path, int_data):
    """
    the method open the csv file with results and calls json encoder
    """
    testcases = os.listdir(results_path)
    for test in testcases:
        if not ".csv" in test:
            continue
        resfile = results_path + '/' + test
        with open(resfile, 'r') as in_file:
            reader = csv.DictReader(in_file)
            tc_data = _prepare_results(reader, int_data)
            _push_results(tc_data)
            tc_names.remove(tc_data['id'])

    # report TCs without results as FAIL
    if tc_names:
        tc_fail = copy.deepcopy(int_data)
        tc_fail['start_time'] = dt.now().strftime('%Y-%m-%d %H:%M:%S')
        tc_fail['stop_time'] = tc_fail['start_time']
        tc_fail['criteria'] = 'FAIL'
        tc_fail['version'] = 'N/A'
        tc_fail['details'] = copy.deepcopy(_DETAILS)
        for tc_name in tc_names:
            tc_fail['dashboard_id'] = "{}_{}".format(tc_name, tc_fail['vswitch'])
            _push_results(tc_fail)

def _prepare_results(reader, int_data):
    """
    the method prepares dashboard details for passed testcases
    """
    version_vswitch = ""
    version_dpdk = ""
    allowed_pkt = ["64", "128", "512", "1024", "1518"]
    vswitch = None
    details = copy.deepcopy(_DETAILS)
    tc_data = copy.deepcopy(int_data)
    tc_data['criteria'] = 'PASS'

    for row_reader in reader:
        if allowed_pkt.count(row_reader['packet_size']) == 0:
            logging.error("The framesize is not supported in opnfv dashboard")
            continue

        # test execution time includes all frame sizes, so start & stop time
        # is the same (repeated) for every framesize in CSV file
        if not 'test_start' in tc_data:
            tc_data['start_time'] = row_reader['start_time']
            tc_data['stop_time'] = row_reader['stop_time']
            tc_data['id'] = row_reader['id']
            # CI job executes/reports TCs per vswitch type
            vswitch = row_reader['vswitch']

        tc_data['dashboard_id'] = "{}_{}".format(row_reader['id'], row_reader['vswitch'].lower())
        if "back2back" in row_reader['id']:
            # 0 B2B frames is quite common, so we can't mark such TC as FAIL
            details[row_reader['packet_size']] = row_reader['b2b_frames']
        else:
            details[row_reader['packet_size']] = row_reader['throughput_rx_fps']
            # 0 PPS is definitelly a failure
            if float(row_reader['throughput_rx_fps']) == 0:
                tc_data['criteria'] = 'FAIL'

    # Create version field
    with open(tc_data['pkg_list'], 'r') as pkg_file:
        for line in pkg_file:
            if "OVS_TAG" in line and vswitch.startswith('Ovs'):
                version_vswitch = line.replace(' ', '')
                version_vswitch = "OVS " + version_vswitch.replace('OVS_TAG?=', '')
            if "VPP_TAG" in line and vswitch.startswith('Vpp'):
                version_vswitch = line.replace(' ', '')
                version_vswitch = "VPP " + version_vswitch.replace('VPP_TAG?=', '')
            if "DPDK_TAG" in line:
                # DPDK_TAG is not used by VPP, it downloads its onw DPDK version
                if vswitch == "OvsDpdkVhost":
                    version_dpdk = line.replace(' ', '')
                    version_dpdk = " DPDK {}".format(
                        version_dpdk.replace('DPDK_TAG?=', ''))

    tc_data['details'] = details
    tc_data['version'] = version_vswitch.replace('\n', '') + version_dpdk.replace('\n', '')

    return tc_data

def _push_results(int_data):
    """
    the method sends testcase details into dashboard database
    """
    url = int_data['db_url'] + "/results"

    # Build body
    body = {"project_name": "vsperf",
            "scenario": "vsperf",
            "start_date": int_data['start_time'],
            "stop_date": int_data['stop_time'],
            "case_name": int_data['dashboard_id'],
            "pod_name": int_data['pod'],
            "installer": int_data['installer'],
            "version": int_data['version'],
            "build_tag": int_data['build_tag'],
            "criteria": int_data['criteria'],
            "details": int_data['details']}

    my_data = requests.post(url, json=body)
    logging.info("Results for %s sent to opnfv, http response: %s", int_data['dashboard_id'], my_data)
    logging.debug("opnfv url: %s", int_data['db_url'])
    logging.debug("the body sent to opnfv")
    logging.debug(body)