aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--qtip/ansible_library/plugins/action/collect.py2
-rw-r--r--qtip/cli/entry.py3
-rw-r--r--resources/metric/nDPI.yaml80
-rw-r--r--resources/template/dpi-metrics.j27
-rw-r--r--resources/template/hosts.sample83
-rw-r--r--resources/template/qpi-report.sample46
-rw-r--r--resources/template/ssh.cfg.sample56
-rw-r--r--resources/template/system-info.sample36
-rw-r--r--setup.cfg1
-rw-r--r--tests/integration/ansible.cfg2
-rw-r--r--tests/integration/group_vars/all1
-rw-r--r--tests/integration/run.yaml11
-rw-r--r--tests/unit/cli/options_test.py3
-rw-r--r--tests/unit/reporter/test_testapi.py116
15 files changed, 226 insertions, 226 deletions
diff --git a/.gitignore b/.gitignore
index 2b3bc644..a098d85d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -75,7 +75,8 @@ ChangeLog
!/tests/data/**/*
# integration data
+/tests/integration/*.retry
+/tests/integration/dump
/tests/integration/hosts
+/tests/integration/reports
/tests/integration/ssh.cfg
-/tests/integration/*.retry
-/tests/integration/reports/*
diff --git a/qtip/ansible_library/plugins/action/collect.py b/qtip/ansible_library/plugins/action/collect.py
index 26e813b8..8c825317 100644
--- a/qtip/ansible_library/plugins/action/collect.py
+++ b/qtip/ansible_library/plugins/action/collect.py
@@ -29,7 +29,7 @@ class ActionModule(ActionBase):
dump = self._task.args.get('dump')
if dump is not None:
- dump_facts(task_vars['inventory_hostname'], [{'name': 'inxi.log', 'content': string}])
+ dump_facts(task_vars['inventory_hostname'], [{'name': dump, 'content': string}])
return collect(patterns, string)
diff --git a/qtip/cli/entry.py b/qtip/cli/entry.py
index 6cf78b58..b84a03d0 100644
--- a/qtip/cli/entry.py
+++ b/qtip/cli/entry.py
@@ -9,6 +9,7 @@
import click
import os
+import pkg_resources as pkg
import sys
@@ -53,7 +54,7 @@ class QtipCli(click.MultiCommand):
invoke_without_command=True)
@click.option('-v', '--verbose', is_flag=True, help='Enable verbose mode.')
@click.option('-d', '--debug', is_flag=True, help='Enable debug mode.')
-@click.version_option('dev')
+@click.version_option(pkg.require("qtip")[0])
@pass_context
def cli(ctx, verbose, debug):
if debug:
diff --git a/resources/metric/nDPI.yaml b/resources/metric/nDPI.yaml
new file mode 100644
index 00000000..0391302a
--- /dev/null
+++ b/resources/metric/nDPI.yaml
@@ -0,0 +1,80 @@
+##############################################################################
+# Copyright (c) 2017 ZTE Corporation and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+- name: prepare sample pcap file
+ get_url:
+ url: "https://build.opnfv.org/artifacts.opnfv.org/qtip/utilities/test.pcap"
+ dest: "{{ qtip_dump }}/localhost/{{ nDPI_file }}"
+ validate_certs: no # required when using proxy for https
+ run_once: yes
+ delegate_to: localhost
+
+- name: installing nDPI dependencies if CentOS
+ yum:
+ name: '{{ item }}'
+ state: present
+ when: ansible_os_family == "RedHat"
+ with_items:
+ - git
+ - gcc
+ - patch
+ - perl-Time-HiRes
+ - autofconf
+ - automake
+ - libpcap-devel libtool
+
+- name: installing nDPI dependencies if Ubuntu
+ apt:
+ name: build-essential
+ state: present
+ when: ansible_os_family == "Debian"
+
+- name: making nDPI temporary directory
+ file:
+ path: "{{ nDPI_cwd }}"
+ state: directory
+
+- name: clone nDPI
+ git:
+ repo: https://github.com/ntop/nDPI.git
+ dest: "{{ nDPI_cwd }}"
+ depth: 1
+ update: no
+
+- name: build nDPI library
+ command: '{{ item }}'
+ with_items:
+ - ./autogen.sh
+ - ./configure
+ - make
+ args:
+ chdir: "{{ nDPI_cwd }}"
+ creates: example/ndpiReader
+
+- name: copy sample packet file
+ copy:
+ src: "{{ qtip_dump }}/localhost/{{ nDPI_file }}"
+ dest: "{{ nDPI_cwd }}/example/{{ nDPI_file }}"
+
+- name:
+ command: "./ndpiReader -i {{ nDPI_file }}"
+ args:
+ chdir: "{{ nDPI_cwd }}/example/"
+ register: nDPI_out
+
+- name: collect DPI metrics from nDPI
+ collect:
+ string: "{{ nDPI_out.stdout }}"
+ patterns:
+ # nDPI throughput: 1.46 M pps / 13.69 Gb/sec
+ # TODO(yujunz) convert "M pps" and "K pps" to number
+ - 'nDPI throughput:\s+?(?P<dpi_pps>\d+.\d+.*) \/ (?P<dpi_bps>\d+.\d+.*)$'
+ dump: 'nDPI.log'
+ register: dpi_metrics
diff --git a/resources/template/dpi-metrics.j2 b/resources/template/dpi-metrics.j2
new file mode 100644
index 00000000..4de200b6
--- /dev/null
+++ b/resources/template/dpi-metrics.j2
@@ -0,0 +1,7 @@
+nDPI throughput
+===============
+
+{% for host in groups['compute'] %}
+{% set dpi_metrics=hostvars[host].dpi_metrics %}
+{{ (hostvars[host].ansible_hostname, "{} / {}".format(dpi_metrics.dpi_pps[0], dpi_metrics.dpi_bps[0]))|justify }}
+{% endfor %}
diff --git a/resources/template/hosts.sample b/resources/template/hosts.sample
deleted file mode 100644
index e37d38ec..00000000
--- a/resources/template/hosts.sample
+++ /dev/null
@@ -1,83 +0,0 @@
-[fuel-master]
-fuel-master
-
-[local]
-localhost ansible_connection=local
-
-[fuel-groups:children]
-ceph-osd
-cluster-1
-compute
-controller
-hw-zte-servers
-mongo
-node-1
-node-2
-node-3
-node-4
-node-5
-node-6
-node-7
-
-[fuel-groups:vars]
-ansible_ssh_common_args=-F ./ssh.cfg
-
-[ceph-osd]
-node-2
-node-4
-node-6
-node-7
-
-[cluster-1]
-node-1
-node-2
-node-3
-node-4
-node-5
-node-6
-node-7
-
-[compute]
-node-2
-node-4
-node-6
-node-7
-
-[controller]
-node-1
-node-3
-node-5
-
-[hw-zte-servers]
-node-1
-node-2
-node-3
-node-4
-node-5
-node-6
-node-7
-
-[mongo]
-node-1
-
-[node-1]
-node-1
-
-[node-2]
-node-2
-
-[node-3]
-node-3
-
-[node-4]
-node-4
-
-[node-5]
-node-5
-
-[node-6]
-node-6
-
-[node-7]
-node-7
-
diff --git a/resources/template/qpi-report.sample b/resources/template/qpi-report.sample
deleted file mode 100644
index cb9e9308..00000000
--- a/resources/template/qpi-report.sample
+++ /dev/null
@@ -1,46 +0,0 @@
-Sample QPI Report
-
-Host: node-26
-QPI: 1.41147857985
-Spec: compute
-
-- SSL: 1.41147857985
- - ssl_rsa: 1.41147857985
- - rsa_sign_512: 1.25261808935
- - rsa_verify_512: 1.33973907536
- - rsa_sign_1024: 1.31933223495
- - rsa_verify_1024: 1.46972456907
- - rsa_sign_2048: 1.8615470852
- - rsa_verify_2048: 1.3683903146
- - rsa_sign_4096: 1.31537708129
- - rsa_verify_4096: 1.36510018898
-
-Host: node-28
-QPI: 1.28082308651
-Spec: compute
-
-- SSL: 1.28082308651
- - ssl_rsa: 1.28082308651
- - rsa_sign_512: 1.13628081136
- - rsa_verify_512: 1.24882238433
- - rsa_sign_1024: 1.16100601465
- - rsa_verify_1024: 1.33382620817
- - rsa_sign_2048: 1.72057174888
- - rsa_verify_2048: 1.23917640038
- - rsa_sign_4096: 1.16846229187
- - rsa_verify_4096: 1.2384388324
-
-Host: node-27
-QPI: 1.41542492777
-Spec: compute
-
-- SSL: 1.41542492777
- - ssl_rsa: 1.41542492777
- - rsa_sign_512: 1.25857845591
- - rsa_verify_512: 1.34193319426
- - rsa_sign_1024: 1.32097981222
- - rsa_verify_1024: 1.4807103336
- - rsa_sign_2048: 1.86378923767
- - rsa_verify_2048: 1.36600306932
- - rsa_sign_4096: 1.31635651322
- - rsa_verify_4096: 1.37504880601
diff --git a/resources/template/ssh.cfg.sample b/resources/template/ssh.cfg.sample
deleted file mode 100644
index efa45ab6..00000000
--- a/resources/template/ssh.cfg.sample
+++ /dev/null
@@ -1,56 +0,0 @@
-Host node-5
- HostName 10.20.5.12
- User root
- # Use `ProxyCommand` for OpenSSH before 7.3
- ProxyCommand ssh -o 'ForwardAgent yes' fuel-master 'ssh-add && nc %h %p'
- # `ProxyJump` is available since OpenSSH 7.3
- # ProxyJump fuel-master
-
-Host node-4
- HostName 10.20.5.14
- User root
- # Use `ProxyCommand` for OpenSSH before 7.3
- ProxyCommand ssh -o 'ForwardAgent yes' fuel-master 'ssh-add && nc %h %p'
- # `ProxyJump` is available since OpenSSH 7.3
- # ProxyJump fuel-master
-
-Host node-7
- HostName 10.20.5.15
- User root
- # Use `ProxyCommand` for OpenSSH before 7.3
- ProxyCommand ssh -o 'ForwardAgent yes' fuel-master 'ssh-add && nc %h %p'
- # `ProxyJump` is available since OpenSSH 7.3
- # ProxyJump fuel-master
-
-Host node-6
- HostName 10.20.5.16
- User root
- # Use `ProxyCommand` for OpenSSH before 7.3
- ProxyCommand ssh -o 'ForwardAgent yes' fuel-master 'ssh-add && nc %h %p'
- # `ProxyJump` is available since OpenSSH 7.3
- # ProxyJump fuel-master
-
-Host node-1
- HostName 10.20.5.10
- User root
- # Use `ProxyCommand` for OpenSSH before 7.3
- ProxyCommand ssh -o 'ForwardAgent yes' fuel-master 'ssh-add && nc %h %p'
- # `ProxyJump` is available since OpenSSH 7.3
- # ProxyJump fuel-master
-
-Host node-3
- HostName 10.20.5.11
- User root
- # Use `ProxyCommand` for OpenSSH before 7.3
- ProxyCommand ssh -o 'ForwardAgent yes' fuel-master 'ssh-add && nc %h %p'
- # `ProxyJump` is available since OpenSSH 7.3
- # ProxyJump fuel-master
-
-Host node-2
- HostName 10.20.5.13
- User root
- # Use `ProxyCommand` for OpenSSH before 7.3
- ProxyCommand ssh -o 'ForwardAgent yes' fuel-master 'ssh-add && nc %h %p'
- # `ProxyJump` is available since OpenSSH 7.3
- # ProxyJump fuel-master
-
diff --git a/resources/template/system-info.sample b/resources/template/system-info.sample
deleted file mode 100644
index 371243e2..00000000
--- a/resources/template/system-info.sample
+++ /dev/null
@@ -1,36 +0,0 @@
-System Information from inxi
-============================
-
-node-26
------------------------------
-
-CPU Brand.................2 Deca core Intel Xeon E5-2650 v3s (-HT-MCP-SMP-) speed/max: 1200/3000 MHz
-Disk............................................................................1200.3GB (0.8% used)
-Host Name.........................................................................node-26.zte.com.cn
-Kernel..............................................................4.4.0-66-generic x86_64 (64 bit)
-Memory.............................................................................3836.1/128524.1MB
-Operating System.................................................................Ubuntu 16.04 xenial
-Product......................................................................................EC600G3
-
-node-28
------------------------------
-
-CPU Brand.................2 Deca core Intel Xeon E5-2650 v3s (-HT-MCP-SMP-) speed/max: 1200/3000 MHz
-Disk............................................................................1200.3GB (0.8% used)
-Host Name.........................................................................node-28.zte.com.cn
-Kernel..............................................................4.4.0-66-generic x86_64 (64 bit)
-Memory.............................................................................3826.6/128524.1MB
-Operating System.................................................................Ubuntu 16.04 xenial
-Product......................................................................................EC600G3
-
-node-27
------------------------------
-
-CPU Brand.................2 Deca core Intel Xeon E5-2650 v3s (-HT-MCP-SMP-) speed/max: 1200/3000 MHz
-Disk............................................................................1200.3GB (0.8% used)
-Host Name.........................................................................node-27.zte.com.cn
-Kernel..............................................................4.4.0-66-generic x86_64 (64 bit)
-Memory.............................................................................3922.4/128524.1MB
-Operating System.................................................................Ubuntu 16.04 xenial
-Product......................................................................................EC600G3
-
diff --git a/setup.cfg b/setup.cfg
index 23103fc5..71b8c8fd 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,6 @@
[metadata]
name = qtip
+version = 5.0.0
summary = Platform Performance Benchmarking
description-file =
README.md
diff --git a/tests/integration/ansible.cfg b/tests/integration/ansible.cfg
index 40e28bcf..30e28480 100644
--- a/tests/integration/ansible.cfg
+++ b/tests/integration/ansible.cfg
@@ -26,3 +26,5 @@ filter_plugins = ../../qtip/ansible_library/plugins/filter
#test_plugins = /usr/share/ansible/plugins/test
#terminal_plugins = /usr/share/ansible/plugins/terminal
#strategy_plugins = /usr/share/ansible/plugins/strategy
+
+callback_whitelist = profile_tasks
diff --git a/tests/integration/group_vars/all b/tests/integration/group_vars/all
index 16a93f46..a84ab51f 100644
--- a/tests/integration/group_vars/all
+++ b/tests/integration/group_vars/all
@@ -1,3 +1,4 @@
qtip_resources: ../../resources
qtip_reports: ./reports
qtip_fixtures: ./fixtures
+qtip_dump: ./dump
diff --git a/tests/integration/run.yaml b/tests/integration/run.yaml
index 10428ac3..e715863f 100644
--- a/tests/integration/run.yaml
+++ b/tests/integration/run.yaml
@@ -21,6 +21,12 @@
- name: ssl metrics
include: "{{ qtip_resources }}/metric/openssl.yaml"
tags: [ssl]
+ - name: DPI metrics
+ include: "{{ qtip_resources }}/metric/nDPI.yaml"
+ vars:
+ nDPI_cwd: "{{ ansible_env.HOME }}/qtip/nDPI"
+ nDPI_file: "dpi.pcap"
+ tags: [dpi]
- hosts: compute
tasks:
@@ -57,6 +63,11 @@
src: "{{ qtip_resources }}/template/qpi-report.j2"
dest: "{{ qtip_reports }}/qpi-report"
tags: [report]
+ - name: create dpi metrics report
+ template:
+ src: "{{ qtip_resources }}/template/dpi-metrics.j2"
+ dest: "{{ qtip_reports }}/dpi-metrics"
+ tags: [report, dpi]
- name: push result to testapi
uri:
url: "{{ testapi_url }}/results"
diff --git a/tests/unit/cli/options_test.py b/tests/unit/cli/options_test.py
index 9dbbe6f3..d7c0f700 100644
--- a/tests/unit/cli/options_test.py
+++ b/tests/unit/cli/options_test.py
@@ -8,6 +8,7 @@
##############################################################################
import pytest
+import re
import sys
from click.testing import CliRunner
@@ -26,7 +27,7 @@ class TestClass(object):
def test_version(self, runner):
result = runner.invoke(cli, ['--version'])
- assert 'dev' in result.output
+ assert re.search(r'\d+\.\d+\.\d+', result.output)
def test_debug(self, runner):
runner.invoke(cli, ['-d'])
diff --git a/tests/unit/reporter/test_testapi.py b/tests/unit/reporter/test_testapi.py
new file mode 100644
index 00000000..85655274
--- /dev/null
+++ b/tests/unit/reporter/test_testapi.py
@@ -0,0 +1,116 @@
+##############################################################################
+# Copyright (c) 2017 akhil.batra@research.iiit.ac.in and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+import mock
+import pytest
+
+from qtip.reporter import testapi
+
+
+@pytest.mark.parametrize("testapi_url, payload", [
+ ("http://testresults.opnfv.org/test/api/v1", {'project_name': 'qtip',
+ 'case_name': 'fake-case',
+ 'pod_name': 'fake_pod',
+ 'installer': 'fake_installer',
+ 'version': '1',
+ 'scenario': 'fake_scenario',
+ 'criteria': 'fake_criteria',
+ 'build_tag': 'fake_tag',
+ 'start_date': 'fake_date',
+ 'stop_date': 'fake_date',
+ 'details': 'fake:details'}),
+])
+@mock.patch('qtip.reporter.testapi.requests')
+def test_testapi_unavailable(mock_request, testapi_url, payload):
+ mock_request.post.return_value.status_code = testapi.requests.codes.unavailable
+ mock_request.post.return_value.reason = 'Service unavailable'
+ testapi.push_results(testapi_url, payload)
+ mock_request.post.assert_called_with(testapi_url + '/results', json=payload)
+ mock_request.post.return_value.raise_for_status.assert_called()
+
+
+@pytest.mark.parametrize("testapi_url, payload", [
+ ("http://testresults.opnfv.org/test/api/v1", {'project_name': 'qtip',
+ 'case_name': 'fake-case',
+ 'pod_name': 'fake_pod',
+ 'installer': 'fake_installer',
+ 'version': '1',
+ 'scenario': 'fake_scenario',
+ 'criteria': 'fake_criteria',
+ 'build_tag': 'fake_tag',
+ 'start_date': 'fake_date',
+ 'stop_date': 'fake_date',
+ 'details': 'fake:details'}),
+])
+@mock.patch('qtip.reporter.testapi.requests')
+def test_push_results_success(mock_request, testapi_url, payload):
+ mock_request.post.return_value.status_code = testapi.requests.codes.ok
+ mock_request.post.return_value.json.return_value = {'href': 'mock_url'}
+ push_response = testapi.push_results(testapi_url, payload)
+ mock_request.post.assert_called_with(testapi_url + '/results', json=payload)
+ assert push_response['href'] == 'mock_url'
+
+
+@pytest.mark.parametrize("testapi_url, payload", [
+ ("http://testresults.opnfv.org/test/api/v1", {'project_name': 'qtip',
+ 'case_name': 'fake-case',
+ 'pod_name': 'fake_pod',
+ 'installer': 'fake_installer',
+ 'version': '1',
+ 'scenario': 'fake_scenario',
+ 'criteria': 'fake_criteria',
+ 'build_tag': 'fake_tag',
+ 'start_date': 'fake_date',
+ 'stop_date': 'fake_date',
+ 'details': 'fake:details'}),
+])
+@mock.patch('qtip.reporter.testapi.requests')
+def test_push_results_not_found(mock_request, testapi_url, payload):
+ mock_request.post.return_value.status_code = testapi.requests.codes.not_found
+ mock_request.post.return_value.reason = 'Not found'
+ testapi.push_results(testapi_url, payload)
+ mock_request.post.assert_called_with(testapi_url + '/results', json=payload)
+ mock_request.post.return_value.raise_for_status.assert_called()
+
+
+@pytest.mark.parametrize("testapi_url, payload", [
+ ("http://testresults.opnfv.org/test/api/v1", {'project_name': 'qtip',
+ 'case_name': 'fake-case',
+ 'pod_name': 'fake_pod',
+ 'installer': 'fake_installer',
+ 'version': '',
+ 'scenario': None,
+ 'criteria': 'fake_criteria',
+ 'build_tag': 'fake_tag',
+ 'start_date': 'fake_date',
+ 'stop_date': 'fake_date',
+ 'details': 'fake:details'}),
+])
+def test_push_results_invalid_params(testapi_url, payload):
+ with pytest.raises(testapi.InvalidParamsError) as error_invalid:
+ testapi.push_results(testapi_url, payload)
+ assert set(error_invalid.value.params) == {'version', 'scenario'}
+
+
+@pytest.mark.parametrize("testapi_url, payload", [
+ ("http://testresults.opnfv.org/test/api/v1", {'project_name': 'qtip',
+ 'case_name': 'fake-case',
+ 'pod_name': 'fake_pod',
+ 'installer': 'fake_installer',
+ 'criteria': 'fake_criteria',
+ 'build_tag': 'fake_tag',
+ 'start_date': 'fake_date',
+ 'stop_date': 'fake_date',
+ 'details': 'fake:details'}),
+])
+def test_push_results_missing_params(testapi_url, payload):
+ with pytest.raises(testapi.MissingParamsError) as error_missing:
+ testapi.push_results(testapi_url, payload)
+ assert set(error_missing.value.params) == {'version', 'scenario'}