diff options
-rw-r--r-- | tools/report/report.jinja | 11 | ||||
-rw-r--r-- | tools/report/report.py | 39 | ||||
-rw-r--r-- | tools/systeminfo.py | 135 | ||||
-rw-r--r-- | vnfs/qemu/qemu.py | 5 | ||||
-rwxr-xr-x | vsperf | 11 |
5 files changed, 162 insertions, 39 deletions
diff --git a/tools/report/report.jinja b/tools/report/report.jinja index 6542a202..f59dba72 100644 --- a/tools/report/report.jinja +++ b/tools/report/report.jinja @@ -61,7 +61,16 @@ Below is the environment that the test was performed in: - CPU cores: {{tests[0].env.cpu_cores}} - Memory: {{tests[0].env.memory}} - Virtual Switch Set-up: {{tests[0].deployment}} -- IxNetwork: {{tests[0].env.ixnetwork_ver}} +- vswitchperf: GIT tag: {{tests[0].env.vsperf['git_tag']}} +- Traffic Generator: {{tests[0].env.traffic_gen['name']}}, Version: {{tests[0].env.traffic_gen['version']}}, GIT tag: {{tests[0].env.traffic_gen['git_tag']}} +- vSwitch: {{tests[0].env.vswitch['name']}}, Version: {{tests[0].env.vswitch['version']}}, GIT tag: {{tests[0].env.vswitch['git_tag']}} +- DPDK Version: {{tests[0].env.dpdk['version']}}, GIT tag: {{tests[0].env.dpdk['git_tag']}} +{%- if 'vnf' in tests[0].env %} +- VNF: {{tests[0].env.vnf['name']}}, Version: {{tests[0].env.vnf['version']}}, GIT tag: {{tests[0].env.vnf['git_tag']}} +- VM images: {% for guest_image in tests[0].env.guest_image %}{{guest_image}} {% endfor %} +- VM loopback apps: {% for loopback_app in tests[0].env.loopback_app %}{{loopback_app['name']}}, Version: {{loopback_app['version']}}, GIT tag: {{loopback_app['git_tag']}} + {% endfor %} +{%- endif %} For each test, a summary of the key test results is provided. {% for test in tests %} diff --git a/tools/report/report.py b/tools/report/report.py index d51ff47d..4264c055 100644 --- a/tools/report/report.py +++ b/tools/report/report.py @@ -1,4 +1,4 @@ -# Copyright 2015 Intel Corporation. +# Copyright 2015-2016 Intel Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,14 +24,14 @@ import jinja2 import logging from core.results.results_constants import ResultsConstants -from conf import settings +from conf import settings as S from tools import systeminfo _TEMPLATE_FILE = 'report.jinja' _ROOT_DIR = os.path.normpath(os.path.dirname(os.path.realpath(__file__))) -def _get_env(): +def _get_env(result): """ Get system configuration. @@ -53,8 +53,18 @@ def _get_env(): 'cpu_cores': systeminfo.get_cpu_cores(), 'memory' : systeminfo.get_memory(), 'platform': systeminfo.get_platform(), + 'vsperf': systeminfo.get_version('vswitchperf'), + 'traffic_gen': systeminfo.get_version(S.getValue('TRAFFICGEN')), + 'vswitch': systeminfo.get_version(S.getValue('VSWITCH')), + 'dpdk': systeminfo.get_version('dpdk'), } + if result[ResultsConstants.DEPLOYMENT].count('v'): + env.update({'vnf': systeminfo.get_version(S.getValue('VNF')), + 'guest_image': S.getValue('GUEST_IMAGE'), + 'loopback_app': list(map(systeminfo.get_version, S.getValue('GUEST_LOOPBACK'))), + }) + return env @@ -78,28 +88,27 @@ def generate(input_file, tc_results, tc_stats): try: for result in tc_results: test_config = {} - for tc_conf in settings.getValue('PERFORMANCE_TESTS'): + for tc_conf in S.getValue('PERFORMANCE_TESTS'): if tc_conf['Name'] == result[ResultsConstants.ID]: test_config = tc_conf break - # remove id and deployment from results but store their values - tc_id = result[ResultsConstants.ID] - tc_deployment = result[ResultsConstants.DEPLOYMENT] - del result[ResultsConstants.ID] - del result[ResultsConstants.DEPLOYMENT] - # pass test results, env details and configuration to template tests.append({ - 'ID': tc_id.upper(), - 'id': tc_id, - 'deployment': tc_deployment, + 'ID': result[ResultsConstants.ID].upper(), + 'id': result[ResultsConstants.ID], + 'deployment': result[ResultsConstants.DEPLOYMENT], 'conf': test_config, 'result': result, - 'env': _get_env(), + 'env': _get_env(result), 'stats': tc_stats }) + # remove id and deployment from results before rendering + # but after _get_env() is called; tests dict has its shallow copy + del result[ResultsConstants.ID] + del result[ResultsConstants.DEPLOYMENT] + template_vars = { 'tests': tests, } @@ -117,6 +126,6 @@ def generate(input_file, tc_results, tc_stats): if __name__ == '__main__': - settings.load_from_dir('conf') + S.load_from_dir('conf') OUT = generate(sys.argv[1], '', '') print('Test report written to "%s"...' % OUT) diff --git a/tools/systeminfo.py b/tools/systeminfo.py index cb9ca6ee..901b334e 100644 --- a/tools/systeminfo.py +++ b/tools/systeminfo.py @@ -1,4 +1,4 @@ -# Copyright 2015 Intel Corporation. +# Copyright 2015-2016 Intel Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,7 +20,25 @@ import platform import subprocess import locale -from conf import settings +from conf import settings as S + +def match_line(file_name, pattern): + """ loops through given file and returns first line matching given pattern + + :returns: string with the matching line without end of line or None + """ + try: + with open(file_name, encoding="latin-1") as file_: + for line in file_: + if not line.strip(): + continue + if not line.strip().startswith(pattern): + continue + + return line.strip().rstrip('\n') + return None + except OSError: + return None def get_os(): """Get distro name. @@ -41,14 +59,8 @@ def get_cpu(): :returns: Return CPU information as a string """ - with open('/proc/cpuinfo') as file_: - for line in file_: - if not line.strip(): - continue - if not line.rstrip('\n').startswith('model name'): - continue - - return line.rstrip('\n').split(':')[1] + cpu = match_line('/proc/cpuinfo', 'model name') + return cpu.split(':')[1] if cpu else cpu def get_nic(): """Get NIC(s) information. @@ -59,7 +71,7 @@ def get_nic(): output = subprocess.check_output('lspci', shell=True) output = output.decode(locale.getdefaultlocale()[1]) for line in output.split('\n'): - for nic_pciid in settings.getValue('WHITELIST_NICS'): + for nic_pciid in S.getValue('WHITELIST_NICS'): if line.startswith(nic_pciid): nics.append(''.join(line.split(':')[2:]).strip()) return ', '.join(nics).strip() @@ -108,14 +120,8 @@ def get_memory(): :returns: amount of system memory as string together with unit """ - with open('/proc/meminfo') as file_: - for line in file_: - if not line.strip(): - continue - if not line.rstrip('\n').startswith('MemTotal'): - continue - - return line.rstrip('\n').split(':')[1].strip() + memory = match_line('/proc/meminfo', 'MemTotal') + return memory.split(':')[1].strip() if memory else memory def get_memory_bytes(): """Get memory information in bytes @@ -145,7 +151,7 @@ def get_pids(proc_names_list): """ try: - pids = subprocess.check_output(['sudo', 'LC_ALL=' + settings.getValue('DEFAULT_CMD_LOCALE'), 'pidof'] + pids = subprocess.check_output(['sudo', 'LC_ALL=' + S.getValue('DEFAULT_CMD_LOCALE'), 'pidof'] + proc_names_list) except subprocess.CalledProcessError: # such process isn't running @@ -160,3 +166,92 @@ def get_pid(proc_name_str): with given name is not running """ return get_pids([proc_name_str]) + +# This function uses long switch per purpose, so let us suppress pylint warning too-many-branches +# pylint: disable=R0912 +def get_version(app_name): + """ Get version of given application and its git tag + + :returns: dictionary {'name' : app_name, 'version' : app_version, 'git_tag' : app_git_tag) in case that + version or git tag are not known or not applicaple, than None is returned for any unknown value + + """ + app_version_file = { + 'ovs' : os.path.join(S.getValue('OVS_DIR'), 'include/openvswitch/version.h'), + 'dpdk' : os.path.join(S.getValue('RTE_SDK'), 'lib/librte_eal/common/include/rte_version.h'), + 'qemu' : os.path.join(S.getValue('QEMU_DIR'), 'VERSION'), + 'l2fwd' : os.path.join(S.getValue('ROOT_DIR'), 'src/l2fwd/l2fwd.c'), + 'ixnet' : os.path.join(S.getValue('TRAFFICGEN_IXNET_LIB_PATH'), 'pkgIndex.tcl') + } + + + def get_git_tag(path): + """ get tag of recent commit from repository located at 'path' + + :returns: git tag in form of string with commit hash or None if there + isn't any git repository at given path + """ + try: + if os.path.isdir(path): + return subprocess.check_output('cd {}; git rev-parse HEAD'.format(path), shell=True, + stderr=subprocess.DEVNULL).decode().rstrip('\n') + elif os.path.isfile(path): + return subprocess.check_output('cd $(dirname {}); git log -1 --pretty="%H" {}'.format(path, path), + shell=True, stderr=subprocess.DEVNULL).decode().rstrip('\n') + else: + return None + except subprocess.CalledProcessError: + return None + + + app_version = None + app_git_tag = None + + if app_name.lower().startswith('ovs'): + app_version = match_line(app_version_file['ovs'], '#define OVS_PACKAGE_VERSION') + if app_version: + app_version = app_version.split('"')[1] + app_git_tag = get_git_tag(S.getValue('OVS_DIR')) + elif app_name.lower() in ['dpdk', 'testpmd']: + tmp_ver = ['', '', ''] + found = False + with open(app_version_file['dpdk']) as file_: + for line in file_: + if not line.strip(): + continue + if line.startswith('#define RTE_VER_MAJOR'): + found = True + tmp_ver[0] = line.rstrip('\n').split(' ')[2] + if line.startswith('#define RTE_VER_MINOR'): + found = True + tmp_ver[1] = line.rstrip('\n').split(' ')[2] + if line.startswith('#define RTE_VER_PATCH_LEVEL'): + found = True + tmp_ver[2] = line.rstrip('\n').split(' ')[2] + + if found: + app_version = '.'.join(tmp_ver) + app_git_tag = get_git_tag(S.getValue('RTE_SDK')) + elif app_name.lower().startswith('qemu'): + app_version = match_line(app_version_file['qemu'], '') + app_git_tag = get_git_tag(S.getValue('QEMU_DIR')) + elif app_name.lower() == 'ixnet': + app_version = match_line(app_version_file['ixnet'], 'package provide IxTclNetwork') + if app_version: + app_version = app_version.split(' ')[3] + elif app_name.lower() == 'dummy': + # get git tag of file with Dummy implementation + app_git_tag = get_git_tag(os.path.join(S.getValue('ROOT_DIR'), 'tools/pkt_gen/dummy/dummy.py')) + elif app_name.lower() == 'vswitchperf': + app_git_tag = get_git_tag(S.getValue('ROOT_DIR')) + elif app_name.lower() == 'l2fwd': + app_version = match_line(app_version_file[app_name], 'MODULE_VERSION') + if app_version: + app_version = app_version.split('"')[1] + app_git_tag = get_git_tag(app_version_file[app_name]) + elif app_name.lower() in ['linux_bridge', 'buildin']: + # without login into running VM, it is not possible to check bridge_utils version + app_version = 'NA' + app_git_tag = 'NA' + + return {'name' : app_name, 'version' : app_version, 'git_tag' : app_git_tag} diff --git a/vnfs/qemu/qemu.py b/vnfs/qemu/qemu.py index bf7b1a90..83eea679 100644 --- a/vnfs/qemu/qemu.py +++ b/vnfs/qemu/qemu.py @@ -1,4 +1,4 @@ -# Copyright 2015 Intel Corporation. +# Copyright 2015-2016 Intel Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -200,7 +200,8 @@ class IVnfQemu(IVnf): """ # set guest loopback application based on VNF configuration # cli option take precedence to config file values - guest_loopback = get_test_param('guest_loopback', S.getValue('GUEST_LOOPBACK')[self._number]) + guest_loopback = S.getValue('GUEST_LOOPBACK')[self._number] + if guest_loopback == 'testpmd': self._login() self._configure_testpmd() @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright 2015 Intel Corporation. +# Copyright 2015-2016 Intel Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import locale sys.dont_write_bytecode = True from conf import settings +from conf import get_test_param from core.loader import Loader from testcases import TestCase from tools import tasks @@ -358,6 +359,14 @@ def main(): logging.error('The selected Duration is not a number') sys.exit(1) + # update global settings + guest_loopback = get_test_param('guest_loopback', None) + if guest_loopback: + tmp_gl = [] + for i in range(len(settings.getValue('GUEST_LOOPBACK'))): + tmp_gl.append(guest_loopback) + settings.setValue('GUEST_LOOPBACK', tmp_gl) + # generate results directory name date = datetime.datetime.fromtimestamp(time.time()) results_dir = "results_" + date.strftime('%Y-%m-%d_%H-%M-%S') |