diff options
66 files changed, 2134 insertions, 774 deletions
@@ -69,6 +69,7 @@ disable= consider-merging-isinstance, consider-using-ternary, duplicate-code, + inconsistent-return-statements, interface-not-implemented, no-else-return, no-self-use, diff --git a/README.rst b/README.rst index 76ea9723c..5cf4fec00 100644 --- a/README.rst +++ b/README.rst @@ -48,7 +48,8 @@ For more information on Yardstick architecture, please read: Installation ------------ -Yardstick supports installation on Ubuntu 14.04 or via a Docker image. +Yardstick supports installation on Ubuntu 14.04, OpenSUSE Leap 42.2, 42.3 and +Tumbleweed or via a Docker image. To learn how to install Yardstick, consult the documentation available online at: diff --git a/ansible/build_yardstick_image.yml b/ansible/build_yardstick_image.yml index bc57bcd48..7f709873e 100644 --- a/ansible/build_yardstick_image.yml +++ b/ansible/build_yardstick_image.yml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. --- -- hosts: localhost +- hosts: jumphost vars: boot_modes: @@ -31,7 +31,8 @@ workspace: "{{ lookup('env', 'workspace')|default('/tmp/workspace/yardstick', true) }}" raw_imgfile_basename: "yardstick-{{ release }}-server.raw" environment: - PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin + - PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin + - "{{ proxy_env }}" tasks: - group_by: @@ -40,7 +41,12 @@ - package: name=parted state=present - set_fact: - imgfile: "{{ workspace }}/yardstick-image.img" + imgfile: "{{ normal_image_file }}" + when: img_property == "normal" + + - set_fact: + imgfile: "{{ nsb_image_file }}" + when: img_property == "nsb" - set_fact: mountdir: "{{ lookup('env', 'mountdir')|default('/mnt/yardstick', true) }}" @@ -196,8 +202,13 @@ nameserver_ip: "{{ ansible_dns.nameservers[0] }}" image_type: vm -- name: include {{ img_modify_playbook }} - include: "{{ img_modify_playbook }}" +- name: include ubuntu_server_cloudimg_modify.yml + include: ubuntu_server_cloudimg_modify.yml + when: img_property == "normal" + +- name: include ubuntu_server_cloudimg_modify_samplevnfs.yml + include: ubuntu_server_cloudimg_modify_samplevnfs.yml + when: img_property == "nsb" - hosts: localhost tasks: diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index edd6564d0..359968277 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -1,6 +1,9 @@ ---
+target_os: "Ubuntu"
+YARD_IMG_ARCH: "amd64"
clone_dest: /opt/tempT
release: xenial
-target_os: Ubuntu
+normal_image_file: "{{ workspace }}/yardstick-image.img"
+nsb_image_file: "{{ workspace }}/yardstick-nsb-image.img"
ubuntu_image_file: /tmp/workspace/yardstick/yardstick-trusty-server.raw
-proxy_env: {}
\ No newline at end of file +proxy_env: {}
diff --git a/ansible/inventory.ini b/ansible/inventory.ini index 31692a777..a5fbaad95 100644 --- a/ansible/inventory.ini +++ b/ansible/inventory.ini @@ -12,3 +12,6 @@ host5 ansible_host=10.1.0.54 ansible_user=root ansible_ssh_pass=root [nodes:children] controller compute + +[jumphost] +localhost ansible_connection=local diff --git a/ansible/nsb_setup.yml b/ansible/nsb_setup.yml index 90fba0b1e..bfe5d2349 100644 --- a/ansible/nsb_setup.yml +++ b/ansible/nsb_setup.yml @@ -12,37 +12,26 @@ # See the License for the specific language governing permissions and # limitations under the License. --- -- include: ubuntu_server_baremetal_deploy_samplevnfs.yml - vars: - YARD_IMG_ARCH: amd64 - -- hosts: localhost - roles: - - install_dependencies - - docker - -- include: build_yardstick_image.yml - vars: - YARD_IMG_ARCH: amd64 - release: xenial - when: openrc_file is defined +#- name: Prepare baremetal machine +# include: ubuntu_server_baremetal_deploy_samplevnfs.yml +# vars: +# YARD_IMG_ARCH: amd64 +# +#- name: Install jumphost dependencies and configure docker +# hosts: jumphost +# environment: +# "{{ proxy_env }}" +# roles: +# - install_dependencies +# - docker -- include: clean_images.yml +- name: "handle all openstack stuff when: openrc_file is defined" + include: prepare_openstack.yml when: openrc_file is defined -- hosts: localhost - post_tasks: - - os_image: - name: yardstick-samplevnfs - is_public: yes - disk_format: qcow2 - container_format: bare - filename: "{{ raw_imgfile }}" - properties: - hw_vif_multiqueue_enabled: true - environment: "{{ openrc }}" - when: openrc_file is defined - +- name: start yardstick container on jumphost + hosts: jumphost + tasks: - name: Start yardstick container docker_container: name: yardstick diff --git a/ansible/prepare_openstack.yml b/ansible/prepare_openstack.yml new file mode 100644 index 000000000..8456c9e59 --- /dev/null +++ b/ansible/prepare_openstack.yml @@ -0,0 +1,44 @@ +# Copyright (c) 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. +--- +- name: convert openrc_file to openrc env dict + hosts: jumphost + vars_files: + - yardstick_config.yml + roles: + - convert_openrc + +### +# Build yardstick image for openstack quest +# check included file for other vars/env +### +- include: build_yardstick_image.yml + vars: + YARD_IMG_ARCH: amd64 + release: xenial + +### +# Delete old yardstick image and flavors +# Upload new image +### +- name: cleanup old openstack images, upload new + hosts: jumphost + vars_files: + - yardstick_config.yml + environment: + "{{ openrc }}" + roles: + - clean_images + - clean_flavors + - create_samplevnfs_image diff --git a/ansible/roles/add_custom_repos/tasks/ubuntu.yml b/ansible/roles/add_custom_repos/tasks/ubuntu.yml index c0ba89c0b..4658fe514 100644 --- a/ansible/roles/add_custom_repos/tasks/ubuntu.yml +++ b/ansible/roles/add_custom_repos/tasks/ubuntu.yml @@ -12,6 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. --- +- name: Check multiverse repository + shell: "apt-cache policy | grep {{ release }}/multiverse" + args: + executable: /bin/bash + register: multiverse_repos + ignore_errors: yes + - name: add custom repos template: src: sources.list.j2 diff --git a/ansible/roles/add_custom_repos/templates/sources.list.j2 b/ansible/roles/add_custom_repos/templates/sources.list.j2 index af741cb10..61fbe43aa 100644 --- a/ansible/roles/add_custom_repos/templates/sources.list.j2 +++ b/ansible/roles/add_custom_repos/templates/sources.list.j2 @@ -1,5 +1,8 @@ {% if YARD_IMG_ARCH == "arm64" %} deb [arch={{ YARD_IMG_ARCH }}] http://ports.ubuntu.com/ {{ release }}-backports main restricted universe multiverse {% else %} -deb http://archive.ubuntu.com/ubuntu/ {{ release }}-backports main restricted universe multiverse +deb [arch=amd64,i386] http://archive.ubuntu.com/ubuntu/ {{ release }}-backports main restricted universe multiverse + {% if multiverse_repos.rc != 0 %} +deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ {{ release }} multiverse + {% endif %} {% endif %} diff --git a/ansible/roles/create_image/tasks/main.yml b/ansible/roles/create_image/tasks/main.yml new file mode 100644 index 000000000..f63489d2d --- /dev/null +++ b/ansible/roles/create_image/tasks/main.yml @@ -0,0 +1,23 @@ +# Copyright (c) 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. +--- +- name: pre-clean openstack enviroment + hosts: yardstick + vars_files: + - yardstick_config.yml + + roles: + - convert_openrc + - clean_images + - clean_flavors diff --git a/ansible/roles/create_samplevnfs_image/tasks/main.yml b/ansible/roles/create_samplevnfs_image/tasks/main.yml new file mode 100644 index 000000000..c83cccab5 --- /dev/null +++ b/ansible/roles/create_samplevnfs_image/tasks/main.yml @@ -0,0 +1,24 @@ +# Copyright (c) 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. +--- +- name: create yardstick-samplevnfs image + when: openrc_file is defined + os_image: + name: yardstick-samplevnfs + is_public: yes + disk_format: qcow2 + container_format: bare + filename: "{{ raw_imgfile }}" + properties: + hw_vif_multiqueue_enabled: true diff --git a/ansible/roles/enable_hugepages_on_boot/tasks/main.yml b/ansible/roles/enable_hugepages_on_boot/tasks/main.yml index 29432d2e4..75526eb19 100755 --- a/ansible/roles/enable_hugepages_on_boot/tasks/main.yml +++ b/ansible/roles/enable_hugepages_on_boot/tasks/main.yml @@ -31,34 +31,37 @@ msg: "Hugepages already set by someone else" when: is_mine_huge.stdout == "" and is_huge.stdout != "" -- name: use 16 for auto num_hugepages and 1G size - set_fact: - num_hugepages: 8 - when: num_hugepages|default("auto") == "auto" +- name: configure hugepages as idempotent block + block: + - name: use 8 for auto num_hugepages and 1G size + set_fact: + num_hugepages: 8 + when: num_hugepages|default("auto") == "auto" -- name: set hugepages in grub - lineinfile: - dest: /etc/default/grub - regexp: '{{ hugepage_param_regex }}' - line: '{{ hugepage_param }}' - state: present + - name: set hugepages in grub + lineinfile: + dest: /etc/default/grub + regexp: '{{ hugepage_param_regex }}' + line: '{{ hugepage_param }}' + state: present -- name: create hugetables mount - file: - path: "{{ hugetable_mount }}" - state: directory + - name: create hugetables mount + file: + path: "{{ hugetable_mount }}" + state: directory -- name: mount hugetlbfs - mount: - name: "{{ hugetable_mount }}" - src: nodev - fstype: hugetlbfs - state: present + - name: mount hugetlbfs + mount: + name: "{{ hugetable_mount }}" + src: nodev + fstype: hugetlbfs + state: present -- service: - name: procps - enabled: yes + - service: + name: procps + enabled: yes -- include: manual_modify_grub.yml - # only tested on Ubuntu, kernel line is probably different on other distros - when: ansible_distribution == "Ubuntu" + - include: manual_modify_grub.yml + # only tested on Ubuntu, kernel line is probably different on other distros + when: ansible_distribution == "Ubuntu" + when: is_mine_huge.stdout == "" diff --git a/ansible/roles/enable_hugepages_on_boot/tasks/manual_modify_grub.yml b/ansible/roles/enable_hugepages_on_boot/tasks/manual_modify_grub.yml index cac10e80e..6fa0c1d25 100644 --- a/ansible/roles/enable_hugepages_on_boot/tasks/manual_modify_grub.yml +++ b/ansible/roles/enable_hugepages_on_boot/tasks/manual_modify_grub.yml @@ -20,16 +20,17 @@ recurse: yes register: grub_files +- name: check if hugepages are already enabled + command: "grep -o 'default_hugepagesz=' {{ item.path }}" + register: hugepage_enabled + ignore_errors: True + with_items: "{{ grub_files.files }}" -- name: added hugepages to grub manually because we can't run update-grub in chroot +- name: add hugepages to grub manually because we can't run update-grub in chroot replace: dest: "{{ item.path }}" - # console= should end the line - regexp: '(linux\s+/boot/vmlinuz.*console=\S+$)' - # default_hugepagesz=1G hugepagesz=1G hugepages=8 + regexp: '(linux\s+/boot/vmlinuz.*$)' replace: '\1 default_hugepagesz={{ huge_pagesize_short[huge_pagesize_mb] }} hugepagesz={{ huge_pagesize_short[huge_pagesize_mb] }} hugepages={{ num_hugepages }}' with_items: "{{ grub_files.files }}" - - - - + # we suppose consistent /boot/grub/grub.cfg files + when: hugepage_enabled['results'][0].stdout == "" diff --git a/ansible/roles/enable_hugepages_on_boot/vars/main.yml b/ansible/roles/enable_hugepages_on_boot/vars/main.yml index acdf02509..6fec347b2 100644 --- a/ansible/roles/enable_hugepages_on_boot/vars/main.yml +++ b/ansible/roles/enable_hugepages_on_boot/vars/main.yml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. --- -hugepage_param_regex: '^GRUB_CMDLINE_LINUX="\$GRUB_CMDLINE_LINUX.*# added by hugepages role' +hugepage_param_regex: '^GRUB_CMDLINE_LINUX="\$GRUB_CMDLINE_LINUX.*" # added by hugepages role' hugepage_param: 'GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX default_hugepagesz={{ huge_pagesize_short[huge_pagesize_mb] }} hugepagesz={{ huge_pagesize_short[huge_pagesize_mb] }} hugepages={{ num_hugepages }}" # added by hugepages role' update_grub: diff --git a/ansible/ubuntu_server_baremetal_deploy_samplevnfs.yml b/ansible/ubuntu_server_baremetal_deploy_samplevnfs.yml index 42a7b2d08..479b45c92 100644 --- a/ansible/ubuntu_server_baremetal_deploy_samplevnfs.yml +++ b/ansible/ubuntu_server_baremetal_deploy_samplevnfs.yml @@ -12,10 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. --- -- hosts: all +- hosts: yardstick-standalone:jumphost vars: clone_dir: /tmp/yardstick-clone - + environment: + "{{ proxy_env }}" roles: - add_custom_repos diff --git a/ansible/yardstick-install-inventory.ini b/ansible/yardstick-install-inventory.ini index e2647b033..e276076cc 100644 --- a/ansible/yardstick-install-inventory.ini +++ b/ansible/yardstick-install-inventory.ini @@ -1,4 +1,20 @@ # the group of systems on which to install yardstick # by default just localhost -[yardstick] +[jumphost] localhost ansible_connection=local + +# section below is only due backward compatibility. +# it will be removed later +[yardstick:children] +jumphost + +[yardstick-standalone] +# uncomment hosts below if you would to test yardstick-standalone/sriov scenarios +#yardstick-standalone-node ansible_host=192.168.1.2 +#yardstick-standalone-node-2 ansible_host=192.168.1.2 + +[all:vars] +# incomment credentials below for yardstick-standalone +#ansible_user=root +#ansible_pass=root + diff --git a/docs/testing/developer/devguide/devguide.rst b/docs/testing/developer/devguide/devguide.rst index 1d47e5605..dade49b75 100755 --- a/docs/testing/developer/devguide/devguide.rst +++ b/docs/testing/developer/devguide/devguide.rst @@ -361,7 +361,7 @@ Verify your patch locally before submitting Once you finish a patch, you can submit it to Gerrit for code review. A developer sends a new patch to Gerrit will trigger patch verify job on Jenkins -CI. The yardstick patch verify job includes python flake8 check, unit test and +CI. The yardstick patch verify job includes python pylint check, unit test and code coverage test. Before you submit your patch, it is recommended to run the patch verification in your local environment first. diff --git a/docs/testing/user/userguide/04-installation.rst b/docs/testing/user/userguide/04-installation.rst index dc528db6c..828c49581 100644 --- a/docs/testing/user/userguide/04-installation.rst +++ b/docs/testing/user/userguide/04-installation.rst @@ -331,6 +331,91 @@ For uninstalling Yardstick, just delete the virtual environment:: rm -rf ~/yardstick_venv +Install Yardstick directly in OpenSUSE +-------------------------------------- + +.. _install-framework: + +You can install Yardstick framework directly in OpenSUSE. + + +Install Yardstick +^^^^^^^^^^^^^^^^^ + +Prerequisite preparation:: + + sudo -EH zypper -n install -y gcc \ + wget \ + git \ + sshpass \ + qemu-tools \ + kpartx \ + libffi-devel \ + libopenssl-devel \ + python \ + python-devel \ + python-virtualenv \ + libxml2-devel \ + libxslt-devel \ + python-setuptools-git + +Create a virtual environment:: + + virtualenv ~/yardstick_venv + export YARDSTICK_VENV=~/yardstick_venv + source ~/yardstick_venv/bin/activate + sudo -EH easy_install -U setuptools + +Download the source code and install Yardstick from it:: + + git clone https://gerrit.opnfv.org/gerrit/yardstick + export YARDSTICK_REPO_DIR=~/yardstick + cd yardstick + sudo -EH python setup.py install + sudo -EH pip install -r requirements.txt + +Install missing python modules:: + + sudo -EH pip install pyyaml \ + oslo_utils \ + oslo_serialization \ + oslo_config \ + paramiko \ + python.heatclient \ + python.novaclient \ + python.glanceclient \ + python.neutronclient \ + scp \ + jinja2 + + +Configure the Yardstick environment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Source the OpenStack environment variables:: + + source DEVSTACK_DIRECTORY/openrc + +Export the Openstack external network. The default installation of Devstack +names the external network public:: + + export EXTERNAL_NETWORK=public + export OS_USERNAME=demo + +Change the API version used by Yardstick to v2.0 (the devstack openrc sets it +to v3):: + + export OS_AUTH_URL=http://PUBLIC_IP_ADDRESS:5000/v2.0 + + +Uninstall Yardstick +^^^^^^^^^^^^^^^^^^^ + +For unistalling Yardstick, just delete the virtual environment:: + + rm -rf ~/yardstick_venv + + Verify the installation ----------------------- diff --git a/docs/testing/user/userguide/12-nsb_installation.rst b/docs/testing/user/userguide/12-nsb_installation.rst index 8cc26acd5..a584ca231 100644 --- a/docs/testing/user/userguide/12-nsb_installation.rst +++ b/docs/testing/user/userguide/12-nsb_installation.rst @@ -112,12 +112,52 @@ Download the source code and install Yardstick from it # git checkout <tag or stable branch> git checkout stable/euphrates - # For Bare-Metal or Standalone Virtualization - ./nsb_setup.sh +Configure the network proxy, either using the environment variables or setting +the global environment file: - # For OpenStack - ./nsb_setup.sh <path to admin-openrc.sh> +.. code-block:: ini + cat /etc/environment + http_proxy='http://proxy.company.com:port' + https_proxy='http://proxy.company.com:port' +.. code-block:: console + export http_proxy='http://proxy.company.com:port' + export https_proxy='http://proxy.company.com:port' + +The last step is to modify the Yardstick installation inventory, used by +Ansible: + +.. code-block:: ini + cat ./ansible/yardstick-install-inventory.ini + [jumphost] + localhost ansible_connection=local + + [yardstick-standalone] + yardstick-standalone-node ansible_host=192.168.1.2 + yardstick-standalone-node-2 ansible_host=192.168.1.3 + + # section below is only due backward compatibility. + # it will be removed later + [yardstick:children] + jumphost + + [all:vars] + ansible_user=root + ansible_pass=root + + +To execute an installation for a Bare-Metal or a Standalone context: + +.. code-block:: console + + ./nsb_setup.sh + + +To execute an installation for an OpenStack context: + +.. code-block:: console + + ./nsb_setup.sh <path to admin-openrc.sh> Above command setup docker with latest yardstick code. To execute diff --git a/etc/yardstick/nodes/zte_pod1.yaml b/etc/yardstick/nodes/zte_pod1.yaml deleted file mode 100644 index ec6e46460..000000000 --- a/etc/yardstick/nodes/zte_pod1.yaml +++ /dev/null @@ -1,50 +0,0 @@ -############################################################################## -# 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 -############################################################################## ---- -# sample config file about the POD information, including the -# name/IP/user/ssh key of Bare Metal and Controllers/Computes -# -# The options of this config file include: -# name: the name of this node -# role: node's role, support role: Master/Controller/Comupte/BareMetal -# ip: the node's IP address -# user: the username for login -# key_filename:the path of the private key file for login - -nodes: -- - name: node1 - role: Controller - ip: 10.20.0.20 - user: root - key_filename: /root/.ssh/id_rsa -- - name: node2 - role: Controller - ip: 10.20.0.21 - user: root - key_filename: /root/.ssh/id_rsa -- - name: node3 - role: Controller - ip: 10.20.0.22 - user: root - key_filename: /root/.ssh/id_rsa -- - name: node4 - role: Compute - ip: 10.20.0.23 - user: root - key_filename: /root/.ssh/id_rsa -- - name: node5 - role: Compute - ip: 10.20.0.24 - user: root - key_filename: /root/.ssh/id_rsa diff --git a/nsb_setup.sh b/nsb_setup.sh index 40293fef9..a983f4de7 100755 --- a/nsb_setup.sh +++ b/nsb_setup.sh @@ -13,37 +13,48 @@ # See the License for the specific language governing permissions and # limitations under the License. -apt-get update > /dev/null 2>&1 -pkg=(python-pip build-essential libssl-dev libffi-dev python3-dev python-dev) -for i in "${pkg[@]}"; do - dpkg-query -W --showformat='${Status}\n' "${i}"|grep "install ok installed" - if [ "$?" -eq "1" ]; then - apt-get -y install "${i}"; - fi -done - -pip install ansible==2.3.2 shade==1.17.0 docker-py==1.10.6 - +# OPENRC handling has to be first due no_proxy if [ $# -eq 1 ]; then OPENRC=$(readlink -f -- "$1") - extra_args="-e openrc_file=${OPENRC}" + extra_args="${extra_args} -e openrc_file=${OPENRC}" source "${OPENRC}" CONTROLLER_IP=$(echo ${OS_AUTH_URL} | sed -ne "s#http://\([0-9a-zA-Z.\-]*\):*[0-9]*/.*#\1#p") - export no_proxy="localhost,127.0.0.1,${CONTROLLER_IP},$no_proxy" fi -if [ "$http_proxy" != "" ] || [ "$https_proxy" != "" ]; then - extra_args="${extra_args} -e @/tmp/proxy.yml" +env_http_proxy=$(sed -ne "s/^http_proxy=[\"\']\(.*\)[\"\']/\1/p" /etc/environment) +if [[ -z ${http_proxy} ]] && [[ ! -z ${env_http_proxy} ]]; then + export http_proxy=${env_http_proxy} +fi +env_https_proxy=$(sed -ne "s/^https_proxy=[\"\']\(.*\)[\"\']/\1/p" /etc/environment) +if [[ -z ${https_proxy} ]] && [[ ! -z ${env_https_proxy} ]]; then + export https_proxy=${env_https_proxy} +fi + +# if http[s]_proxy is set (from env or /etc/environment) prepare proxy for ansible +if [[ ! -z ${http_proxy} ]] || [[ ! -z ${https_proxy} ]]; then + export no_proxy="localhost,127.0.0.1,${CONTROLLER_IP},${no_proxy}" + extra_args="${extra_args} -e @/tmp/proxy.yml " cat <<EOF > /tmp/proxy.yml --- proxy_env: - http_proxy: $http_proxy - https_proxy: $https_proxy - no_proxy: $no_proxy + http_proxy: ${http_proxy} + https_proxy: ${https_proxy} + no_proxy: ${no_proxy} EOF fi +apt-get update > /dev/null 2>&1 +pkg=(python-pip build-essential libssl-dev libffi-dev python3-dev python-dev) +for i in "${pkg[@]}"; do + dpkg-query -W --showformat='${Status}\n' "${i}"|grep "install ok installed" + if [ "$?" -eq "1" ]; then + apt-get -y install "${i}"; + fi +done + +pip install ansible==2.3.2 shade==1.17.0 docker-py==1.10.6 + ANSIBLE_SCRIPTS="ansible" cd ${ANSIBLE_SCRIPTS} &&\ diff --git a/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_1024k_Requests-65000_Concurrency.yaml b/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_1024k_Requests-65000_Concurrency.yaml new file mode 100644 index 000000000..a87996c1a --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_1024k_Requests-65000_Concurrency.yaml @@ -0,0 +1,44 @@ +# Copyright (c) 2016-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. + +--- +schema: yardstick:task:0.1 +scenarios: +- type: NSPerf + traffic_profile: "../../traffic_profiles/http_tests/HTTP_1024k-requests_65000_concurrency.yaml" + topology: vfw_vnf_topology_ixload.yaml + nodes: + tg__0: trafficgen_1.yardstick + vnf__0: vnf.yardstick + options: + framesize: + uplink: {64B: 100} + downlink: {64B: 100} + traffic_type: 4 + rfc2544: + allowed_drop_rate: 0.0001 - 0.0001 + vnf__0: + rules: acl_1rule.yaml + vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} + nfvi_enable: True + runner: + type: Duration + duration: 2 + ixia_profile: ../../traffic_profiles/vfw/HTTP-vFW_IPv4_2Ports.rxf # Need vlan update +context: + type: Node + name: yardstick + nfvi_type: baremetal + file: /etc/yardstick/nodes/pod_ixia.yaml + diff --git a/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_256k_Requests-65000_Concurrency.yaml b/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_256k_Requests-65000_Concurrency.yaml new file mode 100644 index 000000000..82cdd6210 --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_256k_Requests-65000_Concurrency.yaml @@ -0,0 +1,44 @@ +# Copyright (c) 2016-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. + +--- +schema: yardstick:task:0.1 +scenarios: +- type: NSPerf + traffic_profile: "../../traffic_profiles/http_tests/HTTP_256k-requests_65000_concurrency.yaml" + topology: vfw_vnf_topology_ixload.yaml + nodes: + tg__0: trafficgen_1.yardstick + vnf__0: vnf.yardstick + options: + framesize: + uplink: {64B: 100} + downlink: {64B: 100} + traffic_type: 4 + rfc2544: + allowed_drop_rate: 0.0001 - 0.0001 + vnf__0: + rules: acl_1rule.yaml + vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} + nfvi_enable: True + runner: + type: Duration + duration: 2 + ixia_profile: ../../traffic_profiles/vfw/HTTP-vFW_IPv4_2Ports.rxf # Need vlan update +context: + type: Node + name: yardstick + nfvi_type: baremetal + file: /etc/yardstick/nodes/pod_ixia.yaml + diff --git a/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_4k_Requests-65000_Concurrency.yaml b/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_4k_Requests-65000_Concurrency.yaml new file mode 100644 index 000000000..00131b5f9 --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_4k_Requests-65000_Concurrency.yaml @@ -0,0 +1,44 @@ +# Copyright (c) 2016-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. + +--- +schema: yardstick:task:0.1 +scenarios: +- type: NSPerf + traffic_profile: "../../traffic_profiles/http_tests/HTTP_4k-requests_65000_concurrency.yaml" + topology: vfw_vnf_topology_ixload.yaml + nodes: + tg__0: trafficgen_1.yardstick + vnf__0: vnf.yardstick + options: + framesize: + uplink: {64B: 100} + downlink: {64B: 100} + traffic_type: 4 + rfc2544: + allowed_drop_rate: 0.0001 - 0.0001 + vnf__0: + rules: acl_1rule.yaml + vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} + nfvi_enable: True + runner: + type: Duration + duration: 2 + ixia_profile: ../../traffic_profiles/vfw/HTTP-vFW_IPv4_2Ports.rxf # Need vlan update +context: + type: Node + name: yardstick + nfvi_type: baremetal + file: /etc/yardstick/nodes/pod_ixia.yaml + diff --git a/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_512k_Requests-65000_Concurrency.yaml b/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_512k_Requests-65000_Concurrency.yaml new file mode 100644 index 000000000..8fcd66e31 --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_512k_Requests-65000_Concurrency.yaml @@ -0,0 +1,44 @@ +# Copyright (c) 2016-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. + +--- +schema: yardstick:task:0.1 +scenarios: +- type: NSPerf + traffic_profile: "../../traffic_profiles/http_tests/HTTP_512k-requests_65000_concurrency.yaml" + topology: vfw_vnf_topology_ixload.yaml + nodes: + tg__0: trafficgen_1.yardstick + vnf__0: vnf.yardstick + options: + framesize: + uplink: {64B: 100} + downlink: {64B: 100} + traffic_type: 4 + rfc2544: + allowed_drop_rate: 0.0001 - 0.0001 + vnf__0: + rules: acl_1rule.yaml + vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} + nfvi_enable: True + runner: + type: Duration + duration: 2 + ixia_profile: ../../traffic_profiles/vfw/HTTP-vFW_IPv4_2Ports.rxf # Need vlan update +context: + type: Node + name: yardstick + nfvi_type: baremetal + file: /etc/yardstick/nodes/pod_ixia.yaml + diff --git a/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_64k_Requests-65000_Concurrency.yaml b/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_64k_Requests-65000_Concurrency.yaml new file mode 100644 index 000000000..3b354243b --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_64k_Requests-65000_Concurrency.yaml @@ -0,0 +1,43 @@ +# Copyright (c) 2016-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. + +--- +schema: yardstick:task:0.1 +scenarios: +- type: NSPerf + traffic_profile: "../../traffic_profiles/http_tests/HTTP_64k-requests_65000_concurrency.yaml" + topology: vfw_vnf_topology_ixload.yaml + nodes: + tg__0: trafficgen_1.yardstick + vnf__0: vnf.yardstick + options: + framesize: + uplink: {64B: 100} + downlink: {64B: 100} + traffic_type: 4 + rfc2544: + allowed_drop_rate: 0.0001 - 0.0001 + vnf__0: + rules: acl_1rule.yaml + vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} + nfvi_enable: True + runner: + type: Duration + duration: 2 + ixia_profile: ../../traffic_profiles/vfw/HTTP-vFW_IPv4_2Ports.rxf # Need vlan update +context: + type: Node + name: yardstick + nfvi_type: baremetal + file: /etc/yardstick/nodes/pod_ixia.yaml diff --git a/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_1024B_ixia.yaml b/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_1024B_ixia.yaml new file mode 100644 index 000000000..1e95c8c2d --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_1024B_ixia.yaml @@ -0,0 +1,83 @@ +# Copyright (c) 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. + +--- +schema: yardstick:task:0.1 +scenarios: +- type: NSPerf + traffic_profile: ../../traffic_profiles/ixia_ipv4_latency.yaml + topology: vfw_vnf_topology_ixia.yaml + nodes: + tg__0: trafficgen_1.yardstick1 + vnf__0: vnf.yardstick + options: + framesize: + uplink: {1024B: 100} + downlink: {1024B: 100} + flow: + src_ip: [{'tg__0': 'xe0'}] + dst_ip: [{'tg__0': 'xe1'}] + count: 1 + traffic_type: 4 + rfc2544: + allowed_drop_rate: 0.0001 - 0.0001 + vnf__0: + rules: acl_1rule.yaml + vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} + runner: + type: Iteration + iterations: 10 + interval: 35 + ixia_profile: ../../traffic_profiles/vfw/vfw_ipv4_profile_1flows.ixncfg +contexts: + # put node context first, so we don't HEAT deploy if node has errors + - name: yardstick1 + type: Node + file: ixia.yml + - name: yardstick + image: yardstick-samplevnfs + flavor: + vcpus: 10 + ram: 20480 + disk: 6 + extra_specs: + hw:cpu_sockets: 1 + hw:cpu_cores: 10 + hw:cpu_threads: 1 + user: ubuntu + placement_groups: + pgrp1: + policy: "availability" + servers: + vnf: + floating_ip: true + placement: "pgrp1" + networks: + mgmt: + cidr: '10.0.1.0/24' + xe0: + cidr: '10.0.2.0/24' + vld_id: downlink_0 + gateway_ip: 'null' + provider: true + physical_network: phystenant1 + port_security_enabled: False + xe1: + cidr: '10.0.3.0/24' + vld_id: uplink_0 + gateway_ip: 'null' + provider: true + physical_network: phystenant2 + port_security_enabled: False + diff --git a/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_1280B_ixia.yaml b/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_1280B_ixia.yaml new file mode 100644 index 000000000..1a7e147aa --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_1280B_ixia.yaml @@ -0,0 +1,83 @@ +# Copyright (c) 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. + +--- +schema: yardstick:task:0.1 +scenarios: +- type: NSPerf + traffic_profile: ../../traffic_profiles/ixia_ipv4_latency.yaml + topology: vfw_vnf_topology_ixia.yaml + nodes: + tg__0: trafficgen_1.yardstick1 + vnf__0: vnf.yardstick + options: + framesize: + uplink: {1280B: 100} + downlink: {1280B: 100} + flow: + src_ip: [{'tg__0': 'xe0'}] + dst_ip: [{'tg__0': 'xe1'}] + count: 1 + traffic_type: 4 + rfc2544: + allowed_drop_rate: 0.0001 - 0.0001 + vnf__0: + rules: acl_1rule.yaml + vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} + runner: + type: Iteration + iterations: 10 + interval: 35 + ixia_profile: ../../traffic_profiles/vfw/vfw_ipv4_profile_1flows.ixncfg +contexts: + # put node context first, so we don't HEAT deploy if node has errors + - name: yardstick1 + type: Node + file: ixia.yml + - name: yardstick + image: yardstick-samplevnfs + flavor: + vcpus: 10 + ram: 20480 + disk: 6 + extra_specs: + hw:cpu_sockets: 1 + hw:cpu_cores: 10 + hw:cpu_threads: 1 + user: ubuntu + placement_groups: + pgrp1: + policy: "availability" + servers: + vnf: + floating_ip: true + placement: "pgrp1" + networks: + mgmt: + cidr: '10.0.1.0/24' + xe0: + cidr: '10.0.2.0/24' + vld_id: downlink_0 + gateway_ip: 'null' + provider: true + physical_network: phystenant1 + port_security_enabled: False + xe1: + cidr: '10.0.3.0/24' + vld_id: uplink_0 + gateway_ip: 'null' + provider: true + physical_network: phystenant2 + port_security_enabled: False + diff --git a/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_128B_ixia.yaml b/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_128B_ixia.yaml new file mode 100644 index 000000000..9a4e60be1 --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_128B_ixia.yaml @@ -0,0 +1,83 @@ +# Copyright (c) 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. + +--- +schema: yardstick:task:0.1 +scenarios: +- type: NSPerf + traffic_profile: ../../traffic_profiles/ixia_ipv4_latency.yaml + topology: vfw_vnf_topology_ixia.yaml + nodes: + tg__0: trafficgen_1.yardstick1 + vnf__0: vnf.yardstick + options: + framesize: + uplink: {128B: 100} + downlink: {128B: 100} + flow: + src_ip: [{'tg__0': 'xe0'}] + dst_ip: [{'tg__0': 'xe1'}] + count: 1 + traffic_type: 4 + rfc2544: + allowed_drop_rate: 0.0001 - 0.0001 + vnf__0: + rules: acl_1rule.yaml + vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} + runner: + type: Iteration + iterations: 10 + interval: 35 + ixia_profile: ../../traffic_profiles/vfw/vfw_ipv4_profile_1flows.ixncfg +contexts: + # put node context first, so we don't HEAT deploy if node has errors + - name: yardstick1 + type: Node + file: ixia.yml + - name: yardstick + image: yardstick-samplevnfs + flavor: + vcpus: 10 + ram: 20480 + disk: 6 + extra_specs: + hw:cpu_sockets: 1 + hw:cpu_cores: 10 + hw:cpu_threads: 1 + user: ubuntu + placement_groups: + pgrp1: + policy: "availability" + servers: + vnf: + floating_ip: true + placement: "pgrp1" + networks: + mgmt: + cidr: '10.0.1.0/24' + xe0: + cidr: '10.0.2.0/24' + vld_id: downlink_0 + gateway_ip: 'null' + provider: true + physical_network: phystenant1 + port_security_enabled: False + xe1: + cidr: '10.0.3.0/24' + vld_id: uplink_0 + gateway_ip: 'null' + provider: true + physical_network: phystenant2 + port_security_enabled: False + diff --git a/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_1518B_ixia.yaml b/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_1518B_ixia.yaml new file mode 100644 index 000000000..7a1ffd82c --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_1518B_ixia.yaml @@ -0,0 +1,82 @@ +# Copyright (c) 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. + +--- +schema: yardstick:task:0.1 +scenarios: +- type: NSPerf + traffic_profile: ../../traffic_profiles/ixia_ipv4_latency.yaml + topology: vfw_vnf_topology_ixia.yaml + nodes: + tg__0: trafficgen_1.yardstick1 + vnf__0: vnf.yardstick + options: + framesize: + uplink: {1518B: 100} + downlink: {1518B: 100} + flow: + src_ip: [{'tg__0': 'xe0'}] + dst_ip: [{'tg__0': 'xe1'}] + count: 1 + traffic_type: 4 + rfc2544: + allowed_drop_rate: 0.0001 - 0.0001 + vnf__0: + rules: acl_1rule.yaml + vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} + runner: + type: Iteration + iterations: 10 + interval: 35 + ixia_profile: ../../traffic_profiles/vfw/vfw_ipv4_profile_1flows.ixncfg +contexts: + # put node context first, so we don't HEAT deploy if node has errors + - name: yardstick1 + type: Node + file: ixia.yml + - name: yardstick + image: yardstick-samplevnfs + flavor: + vcpus: 10 + ram: 20480 + disk: 6 + extra_specs: + hw:cpu_sockets: 1 + hw:cpu_cores: 10 + hw:cpu_threads: 1 + user: ubuntu + placement_groups: + pgrp1: + policy: "availability" + servers: + vnf: + floating_ip: true + placement: "pgrp1" + networks: + mgmt: + cidr: '10.0.1.0/24' + xe0: + cidr: '10.0.2.0/24' + vld_id: downlink_0 + gateway_ip: 'null' + provider: true + physical_network: phystenant1 + port_security_enabled: False + xe1: + cidr: '10.0.3.0/24' + vld_id: uplink_0 + gateway_ip: 'null' + provider: true + physical_network: phystenant2 + port_security_enabled: False diff --git a/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_256B_ixia.yaml b/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_256B_ixia.yaml new file mode 100644 index 000000000..c06c9ad1a --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_256B_ixia.yaml @@ -0,0 +1,82 @@ +# Copyright (c) 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. + +--- +schema: yardstick:task:0.1 +scenarios: +- type: NSPerf + traffic_profile: ../../traffic_profiles/ixia_ipv4_latency.yaml + topology: vfw_vnf_topology_ixia.yaml + nodes: + tg__0: trafficgen_1.yardstick1 + vnf__0: vnf.yardstick + options: + framesize: + uplink: {256B: 100} + downlink: {256B: 100} + flow: + src_ip: [{'tg__0': 'xe0'}] + dst_ip: [{'tg__0': 'xe1'}] + count: 1 + traffic_type: 4 + rfc2544: + allowed_drop_rate: 0.0001 - 0.0001 + vnf__0: + rules: acl_1rule.yaml + vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} + runner: + type: Iteration + iterations: 10 + interval: 35 + ixia_profile: ../../traffic_profiles/vfw/vfw_ipv4_profile_1flows.ixncfg +contexts: + # put node context first, so we don't HEAT deploy if node has errors + - name: yardstick1 + type: Node + file: ixia.yml + - name: yardstick + image: yardstick-samplevnfs + flavor: + vcpus: 10 + ram: 20480 + disk: 6 + extra_specs: + hw:cpu_sockets: 1 + hw:cpu_cores: 10 + hw:cpu_threads: 1 + user: ubuntu + placement_groups: + pgrp1: + policy: "availability" + servers: + vnf: + floating_ip: true + placement: "pgrp1" + networks: + mgmt: + cidr: '10.0.1.0/24' + xe0: + cidr: '10.0.2.0/24' + vld_id: downlink_0 + gateway_ip: 'null' + provider: true + physical_network: phystenant1 + port_security_enabled: False + xe1: + cidr: '10.0.3.0/24' + vld_id: uplink_0 + gateway_ip: 'null' + provider: true + physical_network: phystenant2 + port_security_enabled: False diff --git a/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_512B_ixia.yaml b/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_512B_ixia.yaml new file mode 100644 index 000000000..798dca293 --- /dev/null +++ b/samples/vnf_samples/nsut/vfw/tc_heat_external_rfc2544_ipv4_1rule_1flow_512B_ixia.yaml @@ -0,0 +1,82 @@ +# Copyright (c) 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. + +--- +schema: yardstick:task:0.1 +scenarios: +- type: NSPerf + traffic_profile: ../../traffic_profiles/ixia_ipv4_latency.yaml + topology: vfw_vnf_topology_ixia.yaml + nodes: + tg__0: trafficgen_1.yardstick1 + vnf__0: vnf.yardstick + options: + framesize: + uplink: {512B: 100} + downlink: {512B: 100} + flow: + src_ip: [{'tg__0': 'xe0'}] + dst_ip: [{'tg__0': 'xe1'}] + count: 1 + traffic_type: 4 + rfc2544: + allowed_drop_rate: 0.0001 - 0.0001 + vnf__0: + rules: acl_1rule.yaml + vnf_config: {lb_config: 'SW', lb_count: 1, worker_config: '1C/1T', worker_threads: 1} + runner: + type: Iteration + iterations: 10 + interval: 35 + ixia_profile: ../../traffic_profiles/vfw/vfw_ipv4_profile_1flows.ixncfg +contexts: + # put node context first, so we don't HEAT deploy if node has errors + - name: yardstick1 + type: Node + file: ixia.yml + - name: yardstick + image: yardstick-samplevnfs + flavor: + vcpus: 10 + ram: 20480 + disk: 6 + extra_specs: + hw:cpu_sockets: 1 + hw:cpu_cores: 10 + hw:cpu_threads: 1 + user: ubuntu + placement_groups: + pgrp1: + policy: "availability" + servers: + vnf: + floating_ip: true + placement: "pgrp1" + networks: + mgmt: + cidr: '10.0.1.0/24' + xe0: + cidr: '10.0.2.0/24' + vld_id: downlink_0 + gateway_ip: 'null' + provider: true + physical_network: phystenant1 + port_security_enabled: False + xe1: + cidr: '10.0.3.0/24' + vld_id: uplink_0 + gateway_ip: 'null' + provider: true + physical_network: phystenant2 + port_security_enabled: False diff --git a/test-requirements.txt b/test-requirements.txt index a635bd1d6..8c59e4595 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -4,11 +4,9 @@ coverage==4.3.4 # Apache 2.0; OSI Approved Apache Software License; http://www.apache.org/licenses/LICENSE-2.0; http://www.apache.org/licenses/LICENSE-2.0 fixtures==3.0.0 # OSI Approved BSD License; OSI Approved Apache Software License -flake8==2.5.4 # MIT; OSI Approved MIT License packaging==16.8.0 # BSD or Apache License, Version 2.0 -pep8==1.7.0 # Expat license; OSI Approved MIT License pyflakes==1.0.0 # MIT; OSI Approved MIT License -pylint +pylint==1.8.1 # GPLv2 python-subunit==1.2.0 # OSI Approved Apache Software License; OSI Approved BSD License testrepository==0.0.20 # OSI Approved BSD License; OSI Approved Apache Software License testtools==2.2.0 # OSI Approved MIT License diff --git a/tests/ci/load_images.sh b/tests/ci/load_images.sh index 666a78b40..80caf07ae 100755 --- a/tests/ci/load_images.sh +++ b/tests/ci/load_images.sh @@ -66,10 +66,7 @@ build_yardstick_image() ANSIBLE_SCRIPTS="${0%/*}/../../ansible" cd ${ANSIBLE_SCRIPTS} &&\ ansible-playbook \ - -e img_modify_playbook='ubuntu_server_cloudimg_modify.yml' \ - -e target_os='Ubuntu' \ - -e YARD_IMG_ARCH='amd64' \ - -e ubuntu_img_file="${QCOW_IMAGE}" \ + -e img_property="normal" \ -vvv -i inventory.ini build_yardstick_image.yml if [ ! -f "${QCOW_IMAGE}" ]; then diff --git a/tests/functional/utils.py b/tests/functional/utils.py index b96d2dd50..d889c0dfa 100755 --- a/tests/functional/utils.py +++ b/tests/functional/utils.py @@ -7,14 +7,12 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -from __future__ import absolute_import - import copy import os -import subprocess from oslo_serialization import jsonutils -from oslo_utils import encodeutils + +from yardstick.common import process class Yardstick(object): @@ -26,38 +24,22 @@ class Yardstick(object): """ - def __init__(self, fake=False): - - self.args = ["yardstick"] + def __init__(self): + self._args = ["yardstick"] self.env = copy.deepcopy(os.environ) - def __del__(self): - pass - - def __call__(self, cmd, getjson=False, report_path=None, raw=False, - suffix=None, extension=None, keep_old=False, - write_report=False): + def __call__(self, cmd, getjson=False): """Call yardstick in the shell - :param cmd: yardstick command - :param getjson: in cases, when yardstick prints JSON, you can catch - output deserialized - TO DO: - :param report_path: if present, yardstick command and its output will - be written to file with passed file name - :param raw: don't write command itself to report file. Only output - will be written + :param cmd: Yardstick command. + :param getjson: If the output is a JSON object, it's deserialized. + :return Command output string. """ if not isinstance(cmd, list): cmd = cmd.split(" ") - try: - output = encodeutils.safe_decode(subprocess.check_output( - self.args + cmd, stderr=subprocess.STDOUT, env=self.env), - 'utf-8') - - if getjson: - return jsonutils.loads(output) - return output - except subprocess.CalledProcessError as e: - raise e + cmd = self._args + cmd + output = process.execute(cmd=cmd) + if getjson: + return jsonutils.loads(output) + return output diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc084.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc084.yaml new file mode 100644 index 000000000..472aabe07 --- /dev/null +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc084.yaml @@ -0,0 +1,67 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd 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 +############################################################################## +--- + +schema: "yardstick:task:0.1" +description: > + Yardstick TC084 config file; + Measure CPU performance using SPEC CPU2006 in Virtual machines; + +{% set provider = provider or none %} +{% set physical_network = physical_network or 'physnet1' %} +{% set segmentation_id = segmentation_id or none %} + +{% set benchmark = benchmark or 'int' %} +{% set runspec_iterations = runspec_iterations or 1 %} +{% set runspec_tune = runspec_tune or 'base' %} +{% set runspec_size = runspec_size or 'ref' %} +{% set runspec_rate = runspec_rate or 1 %} + +scenarios: +- + type: SpecCPU2006_for_VM + + options: + SPECint_benchmark: {{benchmark}} + runspec_iterations: {{runspec_iterations}} + runspec_tune: {{runspec_tune}} + runspec_size: {{runspec_size}} + runspec_rate: {{runspec_rate}} + + host: spec.yardstick-TC084 + + runner: + type: Iteration + iterations: 1 + +context: + name: yardstick-TC084 + image: yardstick-image + flavor: yardstick-flavor + user: ubuntu + + placement_groups: + pgrp1: + policy: "availability" + + servers: + spec: + floating_ip: true + placement: "pgrp1" + + networks: + test: + cidr: '10.0.1.0/24' + {% if provider == "vlan" %} + provider: {{provider}} + physical_network: {{physical_network}} + {% if segmentation_id %} + segmentation_id: {{segmentation_id}} + {% endif %} + {% endif %} diff --git a/tests/unit/benchmark/scenarios/compute/test_spec_cpu_for_vm.py b/tests/unit/benchmark/scenarios/compute/test_spec_cpu_for_vm.py new file mode 100644 index 000000000..c428e1fb8 --- /dev/null +++ b/tests/unit/benchmark/scenarios/compute/test_spec_cpu_for_vm.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python + +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd 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 +############################################################################## + +# Unittest for yardstick.benchmark.scenarios.compute.spec_cpu_for_vm.SpecCPUforVM + +from __future__ import absolute_import + +import unittest + +import mock + +from yardstick.benchmark.scenarios.compute import spec_cpu_for_vm + + +@mock.patch('yardstick.benchmark.scenarios.compute.spec_cpu_for_vm.ssh') +class SpecCPUforVMTestCase(unittest.TestCase): + + def setUp(self): + self.ctx = { + 'host': { + 'ip': '172.16.0.137', + 'user': 'root', + 'key_filename': "mykey.key" + } + } + + self.result = {} + + def test_spec_cpu_successful_setup(self, mock_ssh): + + options = { + "SPECint_benchmark": "perlbench", + "runspec_tune": "all", + "output_format": "all", + "runspec_iterations": "1", + "runspec_size": "test" + } + args = {"options": options} + s = spec_cpu_for_vm.SpecCPUforVM(args, self.ctx) + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + + s.setup() + self.assertIsNotNone(s.client) + self.assertTrue(s.setup_done, True) + + def test_spec_cpu_successful__run_no_sla(self, mock_ssh): + + options = { + "SPECint_benchmark": "perlbench", + "runspec_tune": "all", + "output_format": "all" + } + args = {"options": options} + s = spec_cpu_for_vm.SpecCPUforVM(args, self.ctx) + + mock_ssh.SSH.from_node().execute.return_value = (0, '', '') + mock_ssh.SSH.from_node().get.return_value = (0, '', '') + s.run(self.result) + expected_result = {'SPEC_CPU_result': ''} + self.assertEqual(self.result, expected_result) + + def test_spec_cpu_unsuccessful_script_error(self, mock_ssh): + options = { + "benchmark_subset": "int" + } + args = {"options": options} + s = spec_cpu_for_vm.SpecCPUforVM(args, self.ctx) + + mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR') + self.assertRaises(RuntimeError, s.run, self.result) + +def main(): + unittest.main() + +if __name__ == '__main__': + main() diff --git a/tests/unit/common/test_process.py b/tests/unit/common/test_process.py index 5eee55bcc..1c6dfec27 100644 --- a/tests/unit/common/test_process.py +++ b/tests/unit/common/test_process.py @@ -11,10 +11,13 @@ # 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 unittest import mock +import unittest + +from oslo_utils import encodeutils +from yardstick.common import exceptions from yardstick.common import process @@ -44,3 +47,104 @@ class TerminateChildrenTestcase(unittest.TestCase): def test_no_children(self, mock_multiprocessing): mock_multiprocessing.active_children.return_value = [] process.terminate_children() + + +class ExecuteTestCase(unittest.TestCase): + + RET_CODE_OK = 0 + RET_CODE_WRONG = 1 + + def setUp(self): + self._mock_create_process = mock.patch.object(process, + 'create_process') + self.mock_create_process = self._mock_create_process.start() + self.obj = mock.Mock() + self.cmd = mock.Mock() + self.obj.communicate = mock.Mock() + self.stdout = 'std out' + self.stderr = 'std err' + self.obj.communicate.return_value = (self.stdout, self.stderr) + self.mock_create_process.return_value = (self.obj, self.cmd) + self.input_cmd = 'input cmd' + self.additional_env = mock.Mock() + + def test_execute_with_input(self): + process_input = 'process input' + self.obj.returncode = self.RET_CODE_OK + out = process.execute(self.input_cmd, process_input=process_input, + additional_env=self.additional_env) + self.obj.communicate.assert_called_once_with( + encodeutils.to_utf8(process_input)) + self.mock_create_process.assert_called_once_with( + self.input_cmd, run_as_root=False, + additional_env=self.additional_env) + self.assertEqual(self.stdout, out) + + def test_execute_no_input(self): + self.obj.returncode = self.RET_CODE_OK + out = process.execute(self.input_cmd, + additional_env=self.additional_env) + self.obj.communicate.assert_called_once_with(None) + self.mock_create_process.assert_called_once_with( + self.input_cmd, run_as_root=False, + additional_env=self.additional_env) + self.assertEqual(self.stdout, out) + + def test_execute_exception(self): + self.obj.returncode = self.RET_CODE_WRONG + self.assertRaises(exceptions.ProcessExecutionError, process.execute, + self.input_cmd, additional_env=self.additional_env) + self.obj.communicate.assert_called_once_with(None) + + def test_execute_with_extra_code(self): + self.obj.returncode = self.RET_CODE_WRONG + out = process.execute(self.input_cmd, + additional_env=self.additional_env, + extra_ok_codes=[self.RET_CODE_WRONG]) + self.obj.communicate.assert_called_once_with(None) + self.mock_create_process.assert_called_once_with( + self.input_cmd, run_as_root=False, + additional_env=self.additional_env) + self.assertEqual(self.stdout, out) + + def test_execute_exception_no_check(self): + self.obj.returncode = self.RET_CODE_WRONG + out = process.execute(self.input_cmd, + additional_env=self.additional_env, + check_exit_code=False) + self.obj.communicate.assert_called_once_with(None) + self.mock_create_process.assert_called_once_with( + self.input_cmd, run_as_root=False, + additional_env=self.additional_env) + self.assertEqual(self.stdout, out) + + +class CreateProcessTestCase(unittest.TestCase): + + @mock.patch.object(process, 'subprocess_popen') + def test_process_string_command(self, mock_subprocess_popen): + cmd = 'command' + obj = mock.Mock() + mock_subprocess_popen.return_value = obj + out1, out2 = process.create_process(cmd) + self.assertEqual(obj, out1) + self.assertEqual([cmd], out2) + + @mock.patch.object(process, 'subprocess_popen') + def test_process_list_command(self, mock_subprocess_popen): + cmd = ['command'] + obj = mock.Mock() + mock_subprocess_popen.return_value = obj + out1, out2 = process.create_process(cmd) + self.assertEqual(obj, out1) + self.assertEqual(cmd, out2) + + @mock.patch.object(process, 'subprocess_popen') + def test_process_with_env(self, mock_subprocess_popen): + cmd = ['command'] + obj = mock.Mock() + additional_env = {'var1': 'value1'} + mock_subprocess_popen.return_value = obj + out1, out2 = process.create_process(cmd, additional_env=additional_env) + self.assertEqual(obj, out1) + self.assertEqual(['env', 'var1=value1'] + cmd, out2) diff --git a/tests/unit/common/test_utils.py b/tests/unit/common/test_utils.py index 42b75d1f0..452b93a56 100644 --- a/tests/unit/common/test_utils.py +++ b/tests/unit/common/test_utils.py @@ -11,15 +11,15 @@ from __future__ import absolute_import -import ipaddress -import os -import unittest from copy import deepcopy -from itertools import product, chain - import errno +import ipaddress +from itertools import product, chain import mock +import os +import six from six.moves import configparser +import unittest import yardstick from yardstick.common import utils @@ -775,7 +775,8 @@ class RemoveFileTestCase(unittest.TestCase): def test_remove_file(self): try: utils.remove_file('notexistfile.txt') - except Exception as e: + except Exception as e: # pylint: disable=broad-except + # NOTE(ralonsoh): to narrow the scope of this exception. self.assertTrue(isinstance(e, OSError)) @@ -997,7 +998,8 @@ class TestUtilsIpAddrMethods(unittest.TestCase): self.assertEqual(utils.safe_ip_address(addr), expected, addr) @mock.patch("yardstick.common.utils.logging") - def test_safe_ip_address_negative(self, mock_logging): + def test_safe_ip_address_negative(self, *args): + # NOTE(ralonsoh): check the calls to mocked functions. for value in self.INVALID_IP_ADDRESS_STR_LIST: self.assertIsNone(utils.safe_ip_address(value), value) @@ -1026,7 +1028,8 @@ class TestUtilsIpAddrMethods(unittest.TestCase): self.assertEqual(utils.get_ip_version(addr), 6, addr) @mock.patch("yardstick.common.utils.logging") - def test_get_ip_version_negative(self, mock_logging): + def test_get_ip_version_negative(self, *args): + # NOTE(ralonsoh): check the calls to mocked functions. for value in self.INVALID_IP_ADDRESS_STR_LIST: self.assertIsNone(utils.get_ip_version(value), value) @@ -1055,7 +1058,8 @@ class TestUtilsIpAddrMethods(unittest.TestCase): self.assertEqual(utils.ip_to_hex(value), value) @mock.patch("yardstick.common.utils.logging") - def test_ip_to_hex_negative(self, mock_logging): + def test_ip_to_hex_negative(self, *args): + # NOTE(ralonsoh): check the calls to mocked functions. addr_list = self.GOOD_IP_V4_ADDRESS_STR_LIST mask_list = self.GOOD_IP_V4_MASK_STR_LIST value_iter = (''.join(pair) for pair in product(addr_list, mask_list)) @@ -1063,6 +1067,17 @@ class TestUtilsIpAddrMethods(unittest.TestCase): self.assertEqual(utils.ip_to_hex(value), value) +class SafeDecodeUtf8TestCase(unittest.TestCase): + + @unittest.skipIf(six.PY2, + 'This test should only be launched with Python 3.x') + def test_safe_decode_utf8(self): + _bytes = b'this is a byte array' + out = utils.safe_decode_utf8(_bytes) + self.assertIs(type(out), str) + self.assertEqual('this is a byte array', out) + + def main(): unittest.main() diff --git a/tests/unit/network_services/vnf_generic/vnf/test_acl_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_acl_vnf.py index e9444b493..2a2647a91 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_acl_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_acl_vnf.py @@ -15,8 +15,6 @@ # limitations under the License. # -from __future__ import absolute_import - import unittest import mock import os @@ -241,14 +239,14 @@ class TestAclApproxVnf(unittest.TestCase): 'password': 'r00t', 'VNF model': 'acl_vnf.yaml'}}} - def test___init__(self, mock_process): + def test___init__(self, *args): vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] acl_approx_vnf = AclApproxVnf(name, vnfd) self.assertIsNone(acl_approx_vnf._vnf_process) @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch(SSH_HELPER) - def test_collect_kpi(self, ssh, mock_time, mock_process): + def test_collect_kpi(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -263,7 +261,7 @@ class TestAclApproxVnf(unittest.TestCase): @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch(SSH_HELPER) - def test_vnf_execute_command(self, ssh, mock_time, mock_process): + def test_vnf_execute_command(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -275,7 +273,7 @@ class TestAclApproxVnf(unittest.TestCase): self.assertEqual("", acl_approx_vnf.vnf_execute(cmd)) @mock.patch(SSH_HELPER) - def test_get_stats(self, ssh, mock_process): + def test_get_stats(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -296,7 +294,7 @@ class TestAclApproxVnf(unittest.TestCase): @mock.patch("yardstick.network_services.vnf_generic.vnf.acl_vnf.eval") @mock.patch('yardstick.network_services.vnf_generic.vnf.acl_vnf.open') @mock.patch(SSH_HELPER) - def test_run_acl(self, ssh, mock_open, mock_eval, mock_hex, mock_process): + def test_run_acl(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -317,7 +315,7 @@ class TestAclApproxVnf(unittest.TestCase): @mock.patch("yardstick.network_services.vnf_generic.vnf.acl_vnf.find_relative_file") @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context") @mock.patch(SSH_HELPER) - def test_instantiate(self, ssh, mock_context, mock_yang, mock_find, mock_process): + def test_instantiate(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -333,16 +331,9 @@ class TestAclApproxVnf(unittest.TestCase): self.assertIsNone(acl_approx_vnf.instantiate(self.scenario_cfg, self.context_cfg)) - def test_scale(self, mock_process): - vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - acl_approx_vnf = AclApproxVnf(name, vnfd) - flavor = "" - with self.assertRaises(NotImplementedError): - acl_approx_vnf.scale(flavor) - @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch(SSH_HELPER) - def test_terminate(self, ssh, mock_time, mock_process): + def test_terminate(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -355,6 +346,3 @@ class TestAclApproxVnf(unittest.TestCase): acl_approx_vnf.dpdk_nic_bind = "dpdk_nic_bind.py" acl_approx_vnf._resource_collect_stop = mock.Mock() self.assertEqual(None, acl_approx_vnf.terminate()) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/unit/network_services/vnf_generic/vnf/test_base.py b/tests/unit/network_services/vnf_generic/vnf/test_base.py index f812d67ef..e9488f76f 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_base.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_base.py @@ -17,20 +17,20 @@ # Unittest for yardstick.network_services.vnf_generic.vnf.test_base -from __future__ import absolute_import -import unittest +import multiprocessing import os + import mock -from multiprocessing import Queue +import unittest -from yardstick.network_services.vnf_generic.vnf.base import \ - QueueFileWrapper, GenericVNF, GenericTrafficGen +from yardstick.network_services.vnf_generic.vnf import base from yardstick.ssh import SSH -IP_PIPELINE_CFG_FILE_TPL = """ -arp_route_tbl = ({port0_local_ip_hex},{port0_netmask_hex},1,""" -"""{port1_local_ip_hex}) ({port1_local_ip_hex},{port1_netmask_hex},0,""" -"""{port0_local_ip_hex})""" + +IP_PIPELINE_CFG_FILE_TPL = ("arp_route_tbl = ({port0_local_ip_hex}," + "{port0_netmask_hex},1,{port1_local_ip_hex}) " + "({port1_local_ip_hex},{port1_netmask_hex},0," + "{port0_local_ip_hex})") IP_PIPELINE_ND_CFG_FILE_TPL = """ nd_route_tbl = ({port1_dst_ip_hex6},""" @@ -38,6 +38,111 @@ nd_route_tbl = ({port1_dst_ip_hex6},""" _LOCAL_OBJECT = object() +VNFD_0 = { + 'short-name': 'VpeVnf', + 'vdu': [ + { + 'routing_table': [ + { + 'network': '152.16.100.20', + 'netmask': '255.255.255.0', + 'gateway': '152.16.100.20', + 'if': 'xe0' + }, + { + 'network': '152.16.40.20', + 'netmask': '255.255.255.0', + 'gateway': '152.16.40.20', + 'if': 'xe1' + }, + ], + 'description': 'VPE approximation using DPDK', + 'name': 'vpevnf-baremetal', + 'nd_route_tbl': [ + { + 'network': '0064:ff9b:0:0:0:0:9810:6414', + 'netmask': '112', + 'gateway': '0064:ff9b:0:0:0:0:9810:6414', + 'if': 'xe0' + }, + { + 'network': '0064:ff9b:0:0:0:0:9810:2814', + 'netmask': '112', + 'gateway': '0064:ff9b:0:0:0:0:9810:2814', + 'if': 'xe1' + }, + ], + 'id': 'vpevnf-baremetal', + 'external-interface': [ + { + 'virtual-interface': { + 'dst_mac': '00:00:00:00:00:03', + 'vpci': '0000:05:00.0', + 'local_ip': '152.16.100.19', + 'type': 'PCI-PASSTHROUGH', + 'netmask': '255.255.255.0', + 'dpdk_port_num': 0, + 'bandwidth': '10 Gbps', + 'dst_ip': '152.16.100.20', + 'local_mac': '00:00:00:00:00:01' + }, + 'vnfd-connection-point-ref': 'xe0', + 'name': 'xe0' + }, + { + 'virtual-interface': { + 'dst_mac': '00:00:00:00:00:04', + 'vpci': '0000:05:00.1', + 'local_ip': '152.16.40.19', + 'type': 'PCI-PASSTHROUGH', + 'netmask': '255.255.255.0', + 'dpdk_port_num': 1, + 'bandwidth': '10 Gbps', + 'dst_ip': '152.16.40.20', + 'local_mac': '00:00:00:00:00:02' + }, + 'vnfd-connection-point-ref': 'xe1', + 'name': 'xe1' + }, + ], + }, + ], + 'description': 'Vpe approximation using DPDK', + 'mgmt-interface': { + 'vdu-id': 'vpevnf-baremetal', + 'host': '1.1.1.1', + 'password': 'r00t', + 'user': 'root', + 'ip': '1.1.1.1' + }, + 'benchmark': { + 'kpi': [ + 'packets_in', + 'packets_fwd', + 'packets_dropped', + ], + }, + 'connection-point': [ + { + 'type': 'VPORT', + 'name': 'xe0', + }, + { + 'type': 'VPORT', + 'name': 'xe1', + }, + ], + 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh' +} + +VNFD = { + 'vnfd:vnfd-catalog': { + 'vnfd': [ + VNFD_0, + ] + } +} + class FileAbsPath(object): def __init__(self, module_file): @@ -70,17 +175,17 @@ def mock_ssh(mock_ssh_type, spec=None, exec_result=_LOCAL_OBJECT, run_result=_LO class TestQueueFileWrapper(unittest.TestCase): def setUp(self): self.prompt = "pipeline>" - self.q_in = Queue() - self.q_out = Queue() + self.q_in = multiprocessing.Queue() + self.q_out = multiprocessing.Queue() def test___init__(self): queue_file_wrapper = \ - QueueFileWrapper(self.q_in, self.q_out, self.prompt) + base.QueueFileWrapper(self.q_in, self.q_out, self.prompt) self.assertEqual(queue_file_wrapper.prompt, self.prompt) def test_clear(self): queue_file_wrapper = \ - QueueFileWrapper(self.q_in, self.q_out, self.prompt) + base.QueueFileWrapper(self.q_in, self.q_out, self.prompt) queue_file_wrapper.bufsize = 5 queue_file_wrapper.write("pipeline>") queue_file_wrapper.close() @@ -89,167 +194,45 @@ class TestQueueFileWrapper(unittest.TestCase): def test_close(self): queue_file_wrapper = \ - QueueFileWrapper(self.q_in, self.q_out, self.prompt) + base.QueueFileWrapper(self.q_in, self.q_out, self.prompt) self.assertEqual(None, queue_file_wrapper.close()) def test_read(self): queue_file_wrapper = \ - QueueFileWrapper(self.q_in, self.q_out, self.prompt) + base.QueueFileWrapper(self.q_in, self.q_out, self.prompt) queue_file_wrapper.q_in.put("pipeline>") self.assertEqual("pipeline>", queue_file_wrapper.read(20)) def test_write(self): queue_file_wrapper = \ - QueueFileWrapper(self.q_in, self.q_out, self.prompt) + base.QueueFileWrapper(self.q_in, self.q_out, self.prompt) queue_file_wrapper.write("pipeline>") self.assertIsNotNone(queue_file_wrapper.q_out.empty()) class TestGenericVNF(unittest.TestCase): - VNFD_0 = { - 'short-name': 'VpeVnf', - 'vdu': [ - { - 'routing_table': [ - { - 'network': '152.16.100.20', - 'netmask': '255.255.255.0', - 'gateway': '152.16.100.20', - 'if': 'xe0' - }, - { - 'network': '152.16.40.20', - 'netmask': '255.255.255.0', - 'gateway': '152.16.40.20', - 'if': 'xe1' - }, - ], - 'description': 'VPE approximation using DPDK', - 'name': 'vpevnf-baremetal', - 'nd_route_tbl': [ - { - 'network': '0064:ff9b:0:0:0:0:9810:6414', - 'netmask': '112', - 'gateway': '0064:ff9b:0:0:0:0:9810:6414', - 'if': 'xe0' - }, - { - 'network': '0064:ff9b:0:0:0:0:9810:2814', - 'netmask': '112', - 'gateway': '0064:ff9b:0:0:0:0:9810:2814', - 'if': 'xe1' - }, - ], - 'id': 'vpevnf-baremetal', - 'external-interface': [ - { - 'virtual-interface': { - 'dst_mac': '00:00:00:00:00:03', - 'vpci': '0000:05:00.0', - 'local_ip': '152.16.100.19', - 'type': 'PCI-PASSTHROUGH', - 'netmask': '255.255.255.0', - 'dpdk_port_num': 0, - 'bandwidth': '10 Gbps', - 'dst_ip': '152.16.100.20', - 'local_mac': '00:00:00:00:00:01' - }, - 'vnfd-connection-point-ref': 'xe0', - 'name': 'xe0' - }, - { - 'virtual-interface': { - 'dst_mac': '00:00:00:00:00:04', - 'vpci': '0000:05:00.1', - 'local_ip': '152.16.40.19', - 'type': 'PCI-PASSTHROUGH', - 'netmask': '255.255.255.0', - 'dpdk_port_num': 1, - 'bandwidth': '10 Gbps', - 'dst_ip': '152.16.40.20', - 'local_mac': '00:00:00:00:00:02' - }, - 'vnfd-connection-point-ref': 'xe1', - 'name': 'xe1' - }, - ], - }, - ], - 'description': 'Vpe approximation using DPDK', - 'mgmt-interface': { - 'vdu-id': 'vpevnf-baremetal', - 'host': '1.1.1.1', - 'password': 'r00t', - 'user': 'root', - 'ip': '1.1.1.1' - }, - 'benchmark': { - 'kpi': [ - 'packets_in', - 'packets_fwd', - 'packets_dropped', - ], - }, - 'connection-point': [ - { - 'type': 'VPORT', - 'name': 'xe0', - }, - { - 'type': 'VPORT', - 'name': 'xe1', - }, - ], - 'id': 'VpeApproxVnf', 'name': 'VPEVnfSsh' - } - - VNFD = { - 'vnfd:vnfd-catalog': { - 'vnfd': [ - VNFD_0, - ] - } - } - - def test___init__(self): - generic_vnf = GenericVNF('vnf1', self.VNFD_0) - assert generic_vnf.kpi - - def test_collect_kpi(self): - generic_vnf = GenericVNF('vnf1', self.VNFD_0) - self.assertRaises(NotImplementedError, generic_vnf.collect_kpi) - - def test__get_kpi_definition(self): - vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - generic_vnf = GenericVNF('vnf1', vnfd) - kpi = generic_vnf._get_kpi_definition() - self.assertEqual(kpi, ['packets_in', 'packets_fwd', 'packets_dropped']) - - def test_instantiate(self): - generic_vnf = GenericVNF('vnf1', self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]) - with self.assertRaises(NotImplementedError): - generic_vnf.instantiate({}, {}) - - def test_scale(self): - generic_vnf = GenericVNF('vnf1', self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]) - with self.assertRaises(NotImplementedError): - generic_vnf.scale() - - def test_terminate(self): - generic_vnf = GenericVNF('vnf1', self.VNFD['vnfd:vnfd-catalog']['vnfd'][0]) - with self.assertRaises(NotImplementedError): - generic_vnf.terminate() + def test_definition(self): + """Make sure that the abstract class cannot be instantiated""" + with self.assertRaises(TypeError) as exc: + # pylint: disable=abstract-class-instantiated + base.GenericVNF('vnf1', VNFD['vnfd:vnfd-catalog']['vnfd'][0]) + msg = ("Can't instantiate abstract class GenericVNF with abstract " + "methods collect_kpi, instantiate, scale, terminate, " + "wait_for_instantiate") + self.assertEqual(msg, str(exc.exception)) class TestGenericTrafficGen(unittest.TestCase): def test_definition(self): """Make sure that the abstract class cannot be instantiated""" - vnfd = TestGenericVNF.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + vnfd = VNFD['vnfd:vnfd-catalog']['vnfd'][0] name = 'vnf1' with self.assertRaises(TypeError) as exc: - GenericTrafficGen(name, vnfd) + # pylint: disable=abstract-class-instantiated + base.GenericTrafficGen(name, vnfd) msg = ("Can't instantiate abstract class GenericTrafficGen with " - "abstract methods run_traffic, terminate") + "abstract methods collect_kpi, instantiate, run_traffic, " + "scale, terminate") self.assertEqual(msg, str(exc.exception)) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_cgnapt_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_cgnapt_vnf.py index 832509ea7..f2ce18fb3 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_cgnapt_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_cgnapt_vnf.py @@ -15,14 +15,11 @@ # limitations under the License. # -from __future__ import absolute_import - +from copy import deepcopy import os import unittest import mock -from copy import deepcopy - from tests.unit import STL_MOCKS from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh @@ -305,14 +302,14 @@ class TestCgnaptApproxVnf(unittest.TestCase): def setUp(self): self.scenario_cfg = deepcopy(self.SCENARIO_CFG) - def test___init__(self, mock_process): + def test___init__(self, *args): vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] cgnapt_approx_vnf = CgnaptApproxVnf(name, vnfd) self.assertIsNone(cgnapt_approx_vnf._vnf_process) @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time') @mock.patch(SSH_HELPER) - def test_collect_kpi(self, ssh, mock_time, mock_process): + def test_collect_kpi(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -328,7 +325,7 @@ class TestCgnaptApproxVnf(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time') @mock.patch(SSH_HELPER) - def test_vnf_execute_command(self, ssh, mock_time, mock_process): + def test_vnf_execute_command(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -340,7 +337,7 @@ class TestCgnaptApproxVnf(unittest.TestCase): self.assertEqual("", cgnapt_approx_vnf.vnf_execute(cmd)) @mock.patch(SSH_HELPER) - def test_get_stats(self, ssh, mock_process): + def test_get_stats(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -362,7 +359,7 @@ class TestCgnaptApproxVnf(unittest.TestCase): @mock.patch("yardstick.network_services.vnf_generic.vnf.cgnapt_vnf.eval") @mock.patch('yardstick.network_services.vnf_generic.vnf.cgnapt_vnf.open') @mock.patch(SSH_HELPER) - def test_run_vcgnapt(self, ssh, mock_hex, mock_eval, mock_open, mock_process): + def test_run_vcgnapt(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -377,7 +374,7 @@ class TestCgnaptApproxVnf(unittest.TestCase): @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context") @mock.patch(SSH_HELPER) - def test_instantiate(self, ssh, mock_context, mock_process): + def test_instantiate(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -393,15 +390,9 @@ class TestCgnaptApproxVnf(unittest.TestCase): self.assertIsNone(cgnapt_approx_vnf.instantiate(self.scenario_cfg, self.context_cfg)) - def test_scale(self, mock_process): - vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - cgnapt_approx_vnf = CgnaptApproxVnf(name, vnfd) - flavor = "" - self.assertRaises(NotImplementedError, cgnapt_approx_vnf.scale, flavor) - @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch(SSH_HELPER) - def test_terminate(self, ssh, mock_time, mock_process): + def test_terminate(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -417,7 +408,7 @@ class TestCgnaptApproxVnf(unittest.TestCase): @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch(SSH_HELPER) - def test__vnf_up_post(self, ssh, mock_time, mock_process): + def test__vnf_up_post(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -433,7 +424,7 @@ class TestCgnaptApproxVnf(unittest.TestCase): @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch(SSH_HELPER) - def test__vnf_up_post_short(self, ssh, mock_time, mock_process): + def test__vnf_up_post_short(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -444,7 +435,3 @@ class TestCgnaptApproxVnf(unittest.TestCase): cgnapt_approx_vnf.scenario_helper.scenario_cfg = self.scenario_cfg cgnapt_approx_vnf._resource_collect_stop = mock.Mock() cgnapt_approx_vnf._vnf_up_post() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py b/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py index 84eb5dc0d..ed49c7000 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py @@ -15,13 +15,12 @@ # limitations under the License. # -from __future__ import absolute_import - +from itertools import repeat, chain +import mock import os import socket +import time import unittest -from itertools import repeat, chain -import mock from tests.unit import STL_MOCKS from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper @@ -288,29 +287,32 @@ no data length value """ -@mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time') class TestProxSocketHelper(unittest.TestCase): + + def setUp(self): + self.mock_time_sleep = mock.patch.object(time, 'sleep').start() + @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.socket') - def test___init__(self, mock_socket, mock_time): + def test___init__(self, mock_socket): expected = mock_socket.socket() prox = ProxSocketHelper() result = prox._sock self.assertEqual(result, expected) - def test_connect(self, mock_time): + def test_connect(self): mock_sock = mock.MagicMock() prox = ProxSocketHelper(mock_sock) prox.connect('10.20.30.40', 23456) self.assertEqual(mock_sock.connect.call_count, 1) - def test_get_sock(self, mock_time): + def test_get_sock(self): mock_sock = mock.MagicMock() prox = ProxSocketHelper(mock_sock) result = prox.get_socket() self.assertIs(result, mock_sock) @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.select') - def test_get_data(self, mock_select, mock_time): + def test_get_data(self, mock_select): mock_select.select.side_effect = [[1], [0]] mock_socket = mock.MagicMock() mock_recv = mock_socket.recv() @@ -336,7 +338,7 @@ class TestProxSocketHelper(unittest.TestCase): self.assertEqual(ret, 'jumped over') self.assertEqual(len(prox._pkt_dumps), 3) - def test__parse_socket_data_mixed_data(self, mock_time): + def test__parse_socket_data_mixed_data(self): prox = ProxSocketHelper(mock.MagicMock()) ret = prox._parse_socket_data(PACKET_DUMP_NON_1, False) self.assertEqual(ret, 'not_a_dump,1,2') @@ -346,7 +348,7 @@ class TestProxSocketHelper(unittest.TestCase): self.assertEqual(ret, 'not_a_dump,1,2') self.assertEqual(len(prox._pkt_dumps), 1) - def test__parse_socket_data_bad_data(self, mock_time): + def test__parse_socket_data_bad_data(self): prox = ProxSocketHelper(mock.MagicMock()) with self.assertRaises(ValueError): prox._parse_socket_data(PACKET_DUMP_BAD_1, False) @@ -357,7 +359,7 @@ class TestProxSocketHelper(unittest.TestCase): ret = prox._parse_socket_data(PACKET_DUMP_BAD_3, False) self.assertEqual(ret, 'pktdump,3') - def test__parse_socket_data_pkt_dump_only(self, mock_time): + def test__parse_socket_data_pkt_dump_only(self): prox = ProxSocketHelper(mock.MagicMock()) ret = prox._parse_socket_data('', True) self.assertFalse(ret) @@ -368,20 +370,20 @@ class TestProxSocketHelper(unittest.TestCase): ret = prox._parse_socket_data(PACKET_DUMP_2, True) self.assertTrue(ret) - def test_put_command(self, mock_time): + def test_put_command(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.put_command("data") mock_socket.sendall.assert_called_once() - def test_put_command_socket_error(self, mock_time): + def test_put_command_socket_error(self): mock_socket = mock.MagicMock() mock_socket.sendall.side_effect = OSError prox = ProxSocketHelper(mock_socket) prox.put_command("data") mock_socket.sendall.assert_called_once() - def test_get_packet_dump(self, mock_time): + def test_get_packet_dump(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox._pkt_dumps = [] @@ -391,67 +393,67 @@ class TestProxSocketHelper(unittest.TestCase): self.assertEqual(prox.get_packet_dump(), 234) self.assertEqual(prox._pkt_dumps, []) - def test_stop_all_reset(self, mock_time): + def test_stop_all_reset(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.stop_all_reset() mock_socket.sendall.assert_called() - def test_stop_all(self, mock_time): + def test_stop_all(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.stop_all() mock_socket.sendall.assert_called() - def test_stop(self, mock_time): + def test_stop(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.stop([3, 4, 5], 16) mock_socket.sendall.assert_called() - def test_start_all(self, mock_time): + def test_start_all(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.start_all() mock_socket.sendall.assert_called() - def test_start(self, mock_time): + def test_start(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.start([3, 4, 5]) mock_socket.sendall.assert_called() - def test_reset_stats(self, mock_time): + def test_reset_stats(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.reset_stats() mock_socket.sendall.assert_called() - def test_set_pkt_size(self, mock_time): + def test_set_pkt_size(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.set_pkt_size([3, 4, 5], 1024) self.assertEqual(mock_socket.sendall.call_count, 3) - def test_set_value(self, mock_time): + def test_set_value(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.set_value([3, 4, 5], 10, 20, 30) self.assertEqual(mock_socket.sendall.call_count, 3) - def test_reset_values(self, mock_time): + def test_reset_values(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.reset_values([3, 4, 5]) self.assertEqual(mock_socket.sendall.call_count, 3) - def test_set_speed(self, mock_time): + def test_set_speed(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.set_speed([3, 4, 5], 1000) self.assertEqual(mock_socket.sendall.call_count, 3) - def test_slope_speed(self, mock_time): + def test_slope_speed(self): core_data = [ { 'cores': [3, 4, 5], @@ -473,13 +475,13 @@ class TestProxSocketHelper(unittest.TestCase): prox.slope_speed(core_data, 5, 5) self.assertEqual(set_speed.call_count, 10) - def test_set_pps(self, mock_time): + def test_set_pps(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.set_pps([3, 4, 5], 1000, 512) self.assertEqual(mock_socket.sendall.call_count, 3) - def test_lat_stats(self, mock_time): + def test_lat_stats(self): latency_output = [ '1, 2 , 3', # has white space '4,5', # too short @@ -510,7 +512,7 @@ class TestProxSocketHelper(unittest.TestCase): self.assertEqual(mock_socket.sendall.call_count, 5) self.assertEqual(result, expected) - def test_get_all_tot_stats_error(self, mock_time): + def test_get_all_tot_stats_error(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.get_data = mock.MagicMock(return_value='3,4,5') @@ -518,7 +520,7 @@ class TestProxSocketHelper(unittest.TestCase): result = prox.get_all_tot_stats() self.assertEqual(result, expected) - def test_get_all_tot_stats(self, mock_time): + def test_get_all_tot_stats(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.get_data = mock.MagicMock(return_value='3,4,5,6') @@ -526,7 +528,7 @@ class TestProxSocketHelper(unittest.TestCase): result = prox.get_all_tot_stats() self.assertEqual(result, expected) - def test_hz(self, mock_time): + def test_hz(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.get_data = mock.MagicMock(return_value='3,4,5,6') @@ -534,7 +536,7 @@ class TestProxSocketHelper(unittest.TestCase): result = prox.hz() self.assertEqual(result, expected) - def test_core_stats(self, mock_time): + def test_core_stats(self): core_stats = [ '3,4,5,6', '7,8,9,10,NaN', @@ -548,7 +550,7 @@ class TestProxSocketHelper(unittest.TestCase): result = prox.core_stats([3, 4, 5], 16) self.assertEqual(result, expected) - def test_port_stats(self, mock_time): + def test_port_stats(self): port_stats = [ ','.join(str(n) for n in range(3, 15)), ','.join(str(n) for n in range(8, 32, 2)), @@ -562,7 +564,7 @@ class TestProxSocketHelper(unittest.TestCase): result = prox.port_stats([3, 4, 5]) self.assertEqual(result, expected) - def test_measure_tot_stats(self, mock_time): + def test_measure_tot_stats(self): start_tot = 3, 4, 5, 6 end_tot = 7, 9, 11, 13 delta_tot = 4, 5, 6, 7 @@ -584,7 +586,7 @@ class TestProxSocketHelper(unittest.TestCase): pass self.assertEqual(result, expected) - def test_tot_stats(self, mock_time): + def test_tot_stats(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.get_data = mock.MagicMock(return_value='3,4,5,6') @@ -592,7 +594,7 @@ class TestProxSocketHelper(unittest.TestCase): result = prox.tot_stats() self.assertEqual(result, expected) - def test_tot_ierrors(self, mock_time): + def test_tot_ierrors(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.get_data = mock.MagicMock(return_value='3,4,5,6') @@ -600,25 +602,25 @@ class TestProxSocketHelper(unittest.TestCase): result = prox.tot_ierrors() self.assertEqual(result, expected) - def test_set_count(self, mock_time): + def test_set_count(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.set_count(432, [3, 4, 5]) self.assertEqual(mock_socket.sendall.call_count, 3) - def test_dump_rx(self, mock_time): + def test_dump_rx(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.dump_rx(3, 5, 8) self.assertEqual(mock_socket.sendall.call_count, 1) - def test_quit(self, mock_time): + def test_quit(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.quit() mock_socket.sendall.assert_called() - def test_force_quit(self, mock_time): + def test_force_quit(self): mock_socket = mock.MagicMock() prox = ProxSocketHelper(mock_socket) prox.force_quit() @@ -1062,8 +1064,7 @@ class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase): self.assertEqual(helper._prox_config_data, '44') self.assertEqual(helper.remote_path, '55') - @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.find_relative_file') - def test_build_config(self, mock_find_path): + def test_build_config(self): vnf1 = { 'prox_args': {'-f': ""}, 'prox_path': '/opt/nsb_bin/prox', @@ -1075,10 +1076,9 @@ class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase): ], } - mock_find_path.side_effect = ['1', '2'] - vnfd_helper = mock.MagicMock() - ssh_helper = mock.MagicMock() - ssh_helper.provision_tool.return_value = "/opt/nsb_bin/prox" + vnfd_helper = mock.Mock() + ssh_helper = mock.Mock() + ssh_helper.join_bin_path.return_value = '/opt/nsb_bin/prox' scenario_helper = ScenarioHelper('vnf1') scenario_helper.scenario_cfg = { 'task_path': 'a/b', @@ -1087,12 +1087,16 @@ class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase): }, } - helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) - helper.remote_path = "/tmp/prox.cfg" - expected = "sudo bash -c 'cd /opt/nsb_bin; /opt/nsb_bin/prox -o cli -f -f /tmp/prox.cfg '" - with mock.patch.object(helper, "build_config_file") as mock_build_config: + expected = ("sudo bash -c 'cd /opt/nsb_bin; /opt/nsb_bin/prox -o cli " + "-f -f /tmp/prox.cfg '") + + helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, + scenario_helper) + with mock.patch.object(helper, 'build_config_file') as mock_cfg_file: + helper.remote_path = '/tmp/prox.cfg' prox_cmd = helper.build_config() self.assertEqual(prox_cmd, expected) + mock_cfg_file.assert_called_once() def test__insert_additional_file(self): vnfd_helper = mock.MagicMock() @@ -1256,16 +1260,6 @@ class TestProxDpdkVnfSetupEnvHelper(unittest.TestCase): result = helper.put_string_to_file('my long string', 'a/b') self.assertEqual(result, expected) - def test__build_pipeline_kwarags(self): - vnfd_helper = mock.MagicMock() - ssh_helper = mock.MagicMock() - ssh_helper.provision_tool.return_value = "/tmp/nosuch" - scenario_helper = mock.MagicMock() - - helper = ProxDpdkVnfSetupEnvHelper(vnfd_helper, ssh_helper, scenario_helper) - helper._build_pipeline_kwargs() - self.assertEqual(helper.pipeline_kwargs, {'tool_path': '/tmp/nosuch', 'tool_dir': '/tmp'}) - def test_copy_to_target(self): vnfd_helper = mock.MagicMock() vnfd_helper.interfaces = [] @@ -1416,7 +1410,7 @@ class TestProxResourceHelper(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.RETRY_INTERVAL', 0) @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ProxSocketHelper') - def test_sut(self, mock_socket_helper): + def test_sut(self, *args): helper = ProxResourceHelper(mock.MagicMock()) self.assertIsNone(helper.client) result = helper.sut @@ -1466,7 +1460,7 @@ class TestProxResourceHelper(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time') @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.ProxSocketHelper') - def test__connect(self, mock_socket_helper_type, mock_time): + def test__connect(self, mock_socket_helper_type, *args): client = mock_socket_helper_type() client.connect.side_effect = chain(repeat(socket.error, 5), [None]) @@ -1869,7 +1863,7 @@ class TestProxProfileHelper(unittest.TestCase): self.assertIs(result, expected) @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time') - def test_traffic_context(self, mock_time): + def test_traffic_context(self, *args): setup_helper = mock.MagicMock() setup_helper.vnfd_helper.interfaces = [] diff --git a/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py index e29e8ddcd..769279066 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py @@ -15,8 +15,6 @@ # limitations under the License. # -from __future__ import absolute_import - import errno import os import unittest @@ -316,13 +314,13 @@ class TestProxApproxVnf(unittest.TestCase): } @mock.patch(SSH_HELPER) - def test___init__(self, ssh, mock_time): + def test___init__(self, ssh, *args): mock_ssh(ssh) prox_approx_vnf = ProxApproxVnf(NAME, self.VNFD0) self.assertIsNone(prox_approx_vnf._vnf_process) @mock.patch(SSH_HELPER) - def test_collect_kpi_no_client(self, ssh, mock_time): + def test_collect_kpi_no_client(self, ssh, *args): mock_ssh(ssh) prox_approx_vnf = ProxApproxVnf(NAME, self.VNFD0) @@ -337,7 +335,7 @@ class TestProxApproxVnf(unittest.TestCase): self.assertEqual(result, expected) @mock.patch(SSH_HELPER) - def test_collect_kpi(self, ssh, mock_time): + def test_collect_kpi(self, ssh, *args): mock_ssh(ssh) resource_helper = mock.MagicMock() @@ -357,7 +355,7 @@ class TestProxApproxVnf(unittest.TestCase): self.assertEqual(result, expected) @mock.patch(SSH_HELPER) - def test_collect_kpi_error(self, ssh, mock_time): + def test_collect_kpi_error(self, ssh, *args): mock_ssh(ssh) resource_helper = mock.MagicMock() @@ -370,31 +368,13 @@ class TestProxApproxVnf(unittest.TestCase): with self.assertRaises(RuntimeError): prox_approx_vnf.collect_kpi() - def _get_file_abspath(self, filename, mock_time): + def _get_file_abspath(self, filename, *args): curr_path = os.path.dirname(os.path.abspath(__file__)) file_path = os.path.join(curr_path, filename) return file_path - @mock.patch('yardstick.benchmark.scenarios.networking.vnf_generic.open', create=True) - @mock.patch('yardstick.network_services.helpers.iniparser.open', create=True) - @mock.patch(SSH_HELPER) - def test_run_prox(self, ssh, *_): - mock_ssh(ssh) - - prox_approx_vnf = ProxApproxVnf(NAME, self.VNFD0) - prox_approx_vnf.scenario_helper.scenario_cfg = self.SCENARIO_CFG - prox_approx_vnf.ssh_helper.provision_tool.return_value = '/tool_path12/tool_file34' - prox_approx_vnf.setup_helper.remote_path = 'configs/file56.cfg' - - expected = "sudo bash -c 'cd /tool_path12; " \ - "/tool_path12/tool_file34 -o cli -t -f /tmp/l3-swap-2.cfg '" - - prox_approx_vnf._run() - result = prox_approx_vnf.ssh_helper.run.call_args[0][0] - self.assertEqual(result, expected) - @mock.patch(SSH_HELPER) - def bad_test_instantiate(self, ssh, mock_time): + def bad_test_instantiate(self, *args): prox_approx_vnf = ProxApproxVnf(NAME, self.VNFD0) prox_approx_vnf.scenario_helper = mock.MagicMock() prox_approx_vnf.setup_helper = mock.MagicMock() @@ -403,7 +383,7 @@ class TestProxApproxVnf(unittest.TestCase): prox_approx_vnf.setup_helper.build_config.assert_called_once() @mock.patch(SSH_HELPER) - def test_wait_for_instantiate_panic(self, ssh, mock_time): + def test_wait_for_instantiate_panic(self, ssh, *args): mock_ssh(ssh, exec_result=(1, "", "")) prox_approx_vnf = ProxApproxVnf(NAME, self.VNFD0) prox_approx_vnf._vnf_process = mock.MagicMock(**{"is_alive.return_value": True}) @@ -413,16 +393,9 @@ class TestProxApproxVnf(unittest.TestCase): with self.assertRaises(RuntimeError): prox_approx_vnf.wait_for_instantiate() - @mock.patch(SSH_HELPER) - def test_scale(self, ssh, mock_time): - mock_ssh(ssh) - prox_approx_vnf = ProxApproxVnf(NAME, self.VNFD0) - with self.assertRaises(NotImplementedError): - prox_approx_vnf.scale() - @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.socket') @mock.patch(SSH_HELPER) - def test_terminate(self, ssh, mock_socket, mock_time): + def test_terminate(self, ssh, *args): mock_ssh(ssh) prox_approx_vnf = ProxApproxVnf(NAME, self.VNFD0) prox_approx_vnf._vnf_process = mock.MagicMock() @@ -434,7 +407,7 @@ class TestProxApproxVnf(unittest.TestCase): self.assertIsNone(prox_approx_vnf.terminate()) @mock.patch(SSH_HELPER) - def test__vnf_up_post(self, ssh, mock_time): + def test__vnf_up_post(self, ssh, *args): mock_ssh(ssh) prox_approx_vnf = ProxApproxVnf(NAME, self.VNFD0) prox_approx_vnf.resource_helper = resource_helper = mock.Mock() @@ -443,7 +416,7 @@ class TestProxApproxVnf(unittest.TestCase): self.assertEqual(resource_helper.up_post.call_count, 1) @mock.patch(SSH_HELPER) - def test_vnf_execute_oserror(self, ssh, mock_time): + def test_vnf_execute_oserror(self, ssh, *args): mock_ssh(ssh) prox_approx_vnf = ProxApproxVnf(NAME, self.VNFD0) prox_approx_vnf.resource_helper = resource_helper = mock.Mock() @@ -457,6 +430,3 @@ class TestProxApproxVnf(unittest.TestCase): resource_helper.execute.side_effect = OSError(errno.EADDRINUSE, "") with self.assertRaises(OSError): prox_approx_vnf.vnf_execute("", _ignore_errors=True) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py index 85b10c5a9..beb4f8f9f 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py @@ -15,10 +15,6 @@ # limitations under the License. # -# Unittest for yardstick.network_services.vnf_generic.vnf.sample_vnf - -from __future__ import absolute_import - import unittest import mock from copy import deepcopy @@ -26,8 +22,8 @@ from copy import deepcopy from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh from tests.unit import STL_MOCKS from yardstick.benchmark.contexts.base import Context +from yardstick.common import exceptions as y_exceptions from yardstick.network_services.nfvi.resource import ResourceProfile -from yardstick.network_services.traffic_profile.base import TrafficProfile from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper @@ -571,7 +567,7 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.open') @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.find_relative_file') @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.MultiPortConfig') - def test_build_config(self, mock_multi_port_config_class, mock_find, _): + def test_build_config(self, mock_multi_port_config_class, mock_find, *args): mock_multi_port_config = mock_multi_port_config_class() vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() @@ -610,8 +606,8 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time') @mock.patch('yardstick.ssh.SSH') - def test_setup_vnf_environment(self, _, mock_time): - def execute(cmd, *args, **kwargs): + def test_setup_vnf_environment(self, *args): + def execute(cmd): if cmd.startswith('which '): return exec_failure return exec_success @@ -643,7 +639,7 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): @mock.patch('yardstick.ssh.SSH') def test__setup_dpdk_short(self, _): - def execute_side(cmd, *args, **kwargs): + def execute_side(cmd): if 'joined_path' in cmd: return 0, 'output', '' return 1, 'bad output', 'error output' @@ -691,7 +687,7 @@ class TestDpdkVnfSetupEnvHelper(unittest.TestCase): self.assertEqual(dpdk_setup_helper.socket, 1) @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time') - def test__detect_and_bind_drivers(self, mock_time): + def test__detect_and_bind_drivers(self, *args): vnfd_helper = VnfdHelper(deepcopy(self.VNFD_0)) ssh_helper = mock.Mock() # ssh_helper.execute = mock.Mock(return_value = (0, 'text', '')) @@ -1002,7 +998,7 @@ class TestClientResourceHelper(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG') @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.STLError', new_callable=lambda: MockError) - def test_get_stats_not_connected(self, mock_state_error, mock_logger): + def test_get_stats_not_connected(self, mock_state_error, *args): vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() @@ -1221,7 +1217,7 @@ class TestClientResourceHelper(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG') @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.STLError', new_callable=lambda: MockError) - def test__connect_with_failures(self, mock_error, mock_logger, mock_time): + def test__connect_with_failures(self, mock_error, *args): vnfd_helper = VnfdHelper(self.VNFD_0) ssh_helper = mock.Mock() scenario_helper = mock.Mock() @@ -1393,7 +1389,7 @@ class TestSampleVNFDeployHelper(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time') @mock.patch('subprocess.check_output') - def test_deploy_vnfs_disabled(self, mock_check_output, mock_time): + def test_deploy_vnfs_disabled(self, *args): vnfd_helper = mock.Mock() ssh_helper = mock.Mock() ssh_helper.join_bin_path.return_value = 'joined_path' @@ -1408,7 +1404,7 @@ class TestSampleVNFDeployHelper(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time') @mock.patch('subprocess.check_output') - def test_deploy_vnfs(self, mock_check_output, mock_time): + def test_deploy_vnfs(self, *args): vnfd_helper = mock.Mock() ssh_helper = mock.Mock() ssh_helper.join_bin_path.return_value = 'joined_path' @@ -1422,7 +1418,7 @@ class TestSampleVNFDeployHelper(unittest.TestCase): self.assertEqual(ssh_helper.put.call_count, 1) @mock.patch('subprocess.check_output') - def test_deploy_vnfs_early_success(self, mock_check_output): + def test_deploy_vnfs_early_success(self, *args): vnfd_helper = mock.Mock() ssh_helper = mock.Mock() ssh_helper.join_bin_path.return_value = 'joined_path' @@ -1700,7 +1696,7 @@ class TestSampleVnf(unittest.TestCase): self.assertEqual(result, expected) @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.Process') - def test__start_vnf(self, mock_process_type): + def test__start_vnf(self, *args): vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] sample_vnf = SampleVNF('vnf1', vnfd) sample_vnf._run = mock.Mock() @@ -1754,7 +1750,7 @@ class TestSampleVnf(unittest.TestCase): @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch("yardstick.ssh.SSH") - def test_wait_for_instantiate_empty_queue(self, ssh, mock_time): + def test_wait_for_instantiate_empty_queue(self, ssh, *args): mock_ssh(ssh, exec_result=(1, "", "")) queue_size_list = [ @@ -1798,7 +1794,7 @@ class TestSampleVnf(unittest.TestCase): self.assertIsNotNone(sample_vnf.my_ports) @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") - def test_vnf_execute_with_queue_data(self, mock_time): + def test_vnf_execute_with_queue_data(self, *args): queue_size_list = [ 1, 1, @@ -1843,7 +1839,7 @@ class TestSampleVnf(unittest.TestCase): vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] sample_vnf = SampleVNF('vnf1', vnfd) sample_vnf.APP_NAME = 'sample1' - sample_vnf.COLLECT_KPI = '\s(\d+)\D*(\d+)\D*(\d+)' + sample_vnf.COLLECT_KPI = r'\s(\d+)\D*(\d+)\D*(\d+)' sample_vnf.COLLECT_MAP = { 'k1': 3, 'k2': 1, @@ -1866,7 +1862,7 @@ class TestSampleVnf(unittest.TestCase): vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] sample_vnf = SampleVNF('vnf1', vnfd) sample_vnf.APP_NAME = 'sample1' - sample_vnf.COLLECT_KPI = '\s(\d+)\D*(\d+)\D*(\d+)' + sample_vnf.COLLECT_KPI = r'\s(\d+)\D*(\d+)\D*(\d+)' sample_vnf.get_stats = mock.Mock(return_value='') expected = { @@ -1877,6 +1873,29 @@ class TestSampleVnf(unittest.TestCase): result = sample_vnf.collect_kpi() self.assertDictEqual(result, expected) + def test_scale(self): + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + sample_vnf = SampleVNF('vnf1', vnfd) + self.assertRaises(y_exceptions.FunctionNotImplemented, + sample_vnf.scale) + + def test__run(self): + test_cmd = 'test cmd' + run_kwargs = {'arg1': 'val1', 'arg2': 'val2'} + vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] + sample_vnf = SampleVNF('vnf1', vnfd) + sample_vnf.ssh_helper = mock.Mock() + sample_vnf.setup_helper = mock.Mock() + with mock.patch.object(sample_vnf, '_build_config', + return_value=test_cmd), \ + mock.patch.object(sample_vnf, '_build_run_kwargs'): + sample_vnf.run_kwargs = run_kwargs + sample_vnf._run() + sample_vnf.ssh_helper.drop_connection.assert_called_once() + sample_vnf.ssh_helper.run.assert_called_once_with(test_cmd, + **run_kwargs) + sample_vnf.setup_helper.kill_vnf.assert_called_once() + class TestSampleVNFTrafficGen(unittest.TestCase): @@ -2051,3 +2070,8 @@ class TestSampleVNFTrafficGen(unittest.TestCase): self.assertEqual(sample_vnf_tg._wait_for_process(), 234) mock_proc.is_alive.assert_has_calls([mock.call(), mock.call()]) mock_status.assert_has_calls([mock.call(), mock.call()]) + + def test_scale(self): + sample_vnf_tg = SampleVNFTrafficGen('tg1', self.VNFD_0) + self.assertRaises(y_exceptions.FunctionNotImplemented, + sample_vnf_tg.scale) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_ping.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_ping.py index c1b2d27eb..63b2ac4ab 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_ping.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_ping.py @@ -228,7 +228,7 @@ class TestPingTrafficGen(unittest.TestCase): CMD_KWARGS = { 'target_ip': u'152.16.100.20', 'local_ip': u'152.16.100.19', - 'local_if_name': u'xe0', + 'local_if_name': u'xe0_fake', } @mock.patch("yardstick.ssh.SSH") @@ -270,7 +270,7 @@ class TestPingTrafficGen(unittest.TestCase): mock_ssh(ssh, spec=VnfSshHelper, exec_result=(0, "success", "")) ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0) ping_traffic_gen.setup_helper.ssh_helper = mock.MagicMock( - **{"execute.return_value": (0, "success", "")}) + **{"execute.return_value": (0, "xe0_fake", "")}) self.assertIsInstance(ping_traffic_gen.ssh_helper, mock.Mock) self.assertEqual(ping_traffic_gen._result, {}) @@ -278,24 +278,16 @@ class TestPingTrafficGen(unittest.TestCase): self.assertEqual( ping_traffic_gen.vnfd_helper.interfaces[0]['virtual-interface']['local_iface_name'], - 'success') + 'xe0_fake') self.assertEqual(self.CMD_KWARGS, ping_traffic_gen.resource_helper.cmd_kwargs) self.assertIsNotNone(ping_traffic_gen._result) @mock.patch("yardstick.ssh.SSH") - def test_listen_traffic(self, ssh): + def test_listen_traffic(self, *args): ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0) self.assertIsNone(ping_traffic_gen.listen_traffic({})) @mock.patch("yardstick.ssh.SSH") - def test_scale_negative(self, ssh): - ssh.from_node.return_value.execute.return_value = 0, "success", "" - ssh.from_node.return_value.run.return_value = 0, "success", "" - - ping_traffic_gen = PingTrafficGen('vnf1', self.VNFD_0) - ping_traffic_gen.scale() - - @mock.patch("yardstick.ssh.SSH") def test_terminate(self, ssh): ssh.from_node.return_value.execute.return_value = 0, "success", "" ssh.from_node.return_value.run.return_value = 0, "success", "" diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_prox.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_prox.py index 23d448c5e..7b4d79e02 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_prox.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_prox.py @@ -13,14 +13,13 @@ # limitations under the License. # -from __future__ import absolute_import - import unittest import mock from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh from tests.unit import STL_MOCKS + SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper' NAME = 'vnf__1' @@ -319,14 +318,14 @@ class TestProxTrafficGen(unittest.TestCase): 'upper_bound': 100.0}} @mock.patch(SSH_HELPER) - def test___init__(self, ssh, mock_time): + def test___init__(self, ssh, *args): mock_ssh(ssh) prox_traffic_gen = ProxTrafficGen(NAME, self.VNFD0) self.assertIsNone(prox_traffic_gen._tg_process) self.assertIsNone(prox_traffic_gen._traffic_process) @mock.patch(SSH_HELPER) - def test_collect_kpi(self, ssh, mock_time): + def test_collect_kpi(self, ssh, *args): mock_ssh(ssh) prox_traffic_gen = ProxTrafficGen(NAME, self.VNFD0) @@ -335,10 +334,12 @@ class TestProxTrafficGen(unittest.TestCase): prox_traffic_gen._vnf_wrapper.vnf_execute = mock.Mock(return_value="") self.assertEqual({}, prox_traffic_gen.collect_kpi()) - @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.CpuSysCores') + @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.find_relative_file') + @mock.patch( + 'yardstick.network_services.vnf_generic.vnf.sample_vnf.CpuSysCores') @mock.patch(SSH_HELPER) - def bad_test_instantiate(self, ssh, mock_find, mock_cpu_sys_cores, mock_time): + def bad_test_instantiate(self, ssh, mock_cpu_sys_cores, *args): mock_ssh(ssh) mock_cpu_sys_cores.get_core_socket.return_value = {'0': '01234'} @@ -381,7 +382,7 @@ class TestProxTrafficGen(unittest.TestCase): prox_traffic_gen.instantiate(scenario_cfg, {}) @mock.patch(SSH_HELPER) - def test__traffic_runner(self, ssh, mock_time): + def test__traffic_runner(self, ssh, *args): mock_ssh(ssh) mock_traffic_profile = mock.Mock(autospec=TrafficProfile) @@ -399,17 +400,9 @@ class TestProxTrafficGen(unittest.TestCase): sut._connect_client.get_stats = mock.Mock(return_value="0") sut._traffic_runner(mock_traffic_profile) - @mock.patch(SSH_HELPER) - def test_scale(self, ssh, mock_time): - mock_ssh(ssh, exec_result=(1, "", "")) - vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - prox_traffic_gen = ProxTrafficGen(NAME, vnfd) - with self.assertRaises(NotImplementedError): - prox_traffic_gen.scale('') - @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.socket') @mock.patch(SSH_HELPER) - def test_listen_traffic(self, ssh, mock_socket, mock_time): + def test_listen_traffic(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] prox_traffic_gen = ProxTrafficGen(NAME, vnfd) @@ -417,7 +410,7 @@ class TestProxTrafficGen(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.socket') @mock.patch(SSH_HELPER) - def test_terminate(self, ssh, mock_socket, mock_time): + def test_terminate(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] prox_traffic_gen = ProxTrafficGen(NAME, vnfd) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py index f62a0fb3b..e9f718cb7 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_ixia.py @@ -15,8 +15,6 @@ # limitations under the License. # -from __future__ import absolute_import - import os import unittest import mock @@ -40,14 +38,14 @@ NAME = "tg__1" @mock.patch("yardstick.network_services.vnf_generic.vnf.tg_rfc2544_ixia.IxNextgen") class TestIxiaResourceHelper(unittest.TestCase): - def test___init___with_custom_rfc_helper(self, mock_ix_nextgen): + def test___init___with_custom_rfc_helper(self, *args): class MyRfcHelper(IxiaRfc2544Helper): pass ixia_resource_helper = IxiaResourceHelper(mock.Mock(), MyRfcHelper) self.assertIsInstance(ixia_resource_helper.rfc_helper, MyRfcHelper) - def test_stop_collect_with_client(self, mock_ix_nextgen): + def test_stop_collect_with_client(self, *args): mock_client = mock.Mock() ixia_resource_helper = IxiaResourceHelper(mock.Mock()) @@ -154,16 +152,17 @@ class TestIXIATrafficGen(unittest.TestCase): 'file': '/etc/yardstick/nodes/pod.yaml'}, 'schema': 'yardstick:task:0.1'} - def test___init__(self, mock_ixnextgen): + def test___init__(self, *args): with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) ssh_mock.execute = \ mock.Mock(return_value=(0, "", "")) ssh.from_node.return_value = ssh_mock vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - ixnet_traffic_gen = IxiaTrafficGen(NAME, vnfd) + # NOTE(ralonsoh): check the object returned. + IxiaTrafficGen(NAME, vnfd) - def test_listen_traffic(self, mock_ixnextgen): + def test_listen_traffic(self, *args): with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) ssh_mock.execute = \ @@ -173,7 +172,7 @@ class TestIXIATrafficGen(unittest.TestCase): ixnet_traffic_gen = IxiaTrafficGen(NAME, vnfd) self.assertEqual(None, ixnet_traffic_gen.listen_traffic({})) - def test_instantiate(self, mock_ixnextgen): + def test_instantiate(self, *args): with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) ssh_mock.execute = \ @@ -203,7 +202,7 @@ class TestIXIATrafficGen(unittest.TestCase): IOError, ixnet_traffic_gen.instantiate(scenario_cfg, {})) - def test_collect_kpi(self, mock_ixnextgen): + def test_collect_kpi(self, *args): with mock.patch("yardstick.ssh.SSH") as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) ssh_mock.execute = \ @@ -215,7 +214,7 @@ class TestIXIATrafficGen(unittest.TestCase): restult = ixnet_traffic_gen.collect_kpi() self.assertEqual({}, restult) - def test_terminate(self, mock_ixnextgen): + def test_terminate(self, *args): with mock.patch("yardstick.ssh.SSH") as ssh: vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] ssh_mock = mock.Mock(autospec=ssh.SSH) @@ -236,19 +235,14 @@ class TestIXIATrafficGen(unittest.TestCase): file_path = os.path.join(curr_path, filename) return file_path - def test_scale(self, mock_ix_nextgen): - vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - sut = IxiaTrafficGen('vnf1', vnfd) - sut.scale() - - def test__check_status(self, mock_ix_nextgen): + def test__check_status(self, *args): vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] sut = IxiaTrafficGen('vnf1', vnfd) sut._check_status() @mock.patch("yardstick.network_services.vnf_generic.vnf.tg_rfc2544_ixia.time") @mock.patch("yardstick.ssh.SSH") - def test_traffic_runner(self, mock_ixnextgen, mock_ssh, mock_time): + def test_traffic_runner(self, mock_ssh, *args): mock_traffic_profile = mock.Mock(autospec=TrafficProfile) mock_traffic_profile.get_traffic_definition.return_value = "64" mock_traffic_profile.params = self.TRAFFIC_PROFILE diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_trex.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_trex.py index 637706fb4..7342cfcdc 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_trex.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_trex.py @@ -331,15 +331,6 @@ class TestTrexTrafficGenRFC(unittest.TestCase): trex_traffic_gen.resource_helper.ssh_helper = mock.MagicMock() self.assertIsNone(trex_traffic_gen.resource_helper.generate_cfg()) - def test_scale(self): - with mock.patch(SSH_HELPER) as ssh: - ssh_mock = mock.Mock(autospec=ssh.SSH) - ssh_mock.execute = mock.Mock(return_value=(0, "", "")) - ssh_mock.run = mock.Mock(return_value=(0, "", "")) - ssh.from_node.return_value = ssh_mock - trex_traffic_gen = TrexTrafficGenRFC('vnf1', self.VNFD_0) - trex_traffic_gen.scale('') - def test_terminate(self): with mock.patch(SSH_HELPER) as ssh: ssh_mock = mock.Mock(autospec=ssh.SSH) diff --git a/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py b/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py index a2a5058fc..618071507 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_tg_trex.py @@ -15,18 +15,16 @@ # limitations under the License. # -from __future__ import absolute_import - -import unittest - import copy import mock -SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper' +import unittest from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh from tests.unit import STL_MOCKS + +SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper' NAME = 'vnf_1' STLClient = mock.MagicMock() @@ -469,13 +467,6 @@ class TestTrexTrafficGen(unittest.TestCase): self.assertIsNotNone(result) @mock.patch(SSH_HELPER) - def test_scale(self, ssh): - mock_ssh(ssh, exec_result=(1, "", "")) - vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - trex_traffic_gen = TrexTrafficGen(NAME, vnfd) - trex_traffic_gen.scale('') - - @mock.patch(SSH_HELPER) def test_terminate(self, ssh): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] diff --git a/tests/unit/network_services/vnf_generic/vnf/test_udp_replay.py b/tests/unit/network_services/vnf_generic/vnf/test_udp_replay.py index d4d3439f3..635ce2735 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_udp_replay.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_udp_replay.py @@ -15,26 +15,24 @@ # limitations under the License. # -from __future__ import absolute_import - import unittest import mock import os from tests.unit import STL_MOCKS -SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper' +from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh +SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper' + STLClient = mock.MagicMock() stl_patch = mock.patch.dict("sys.modules", STL_MOCKS) stl_patch.start() if stl_patch: from yardstick.network_services.vnf_generic.vnf.udp_replay import UdpReplayApproxVnf - from yardstick.network_services.nfvi.resource import ResourceProfile from yardstick.network_services.vnf_generic.vnf.sample_vnf import ScenarioHelper -from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh TEST_FILE_YAML = 'nsb_test_case.yaml' @@ -329,13 +327,13 @@ class TestUdpReplayApproxVnf(unittest.TestCase): } } - def test___init__(self, _): + def test___init__(self, *args): udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0) self.assertIsNone(udp_replay_approx_vnf._vnf_process) @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch(SSH_HELPER) - def test_collect_kpi(self, ssh, mock_time, _): + def test_collect_kpi(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD_0 @@ -354,7 +352,7 @@ class TestUdpReplayApproxVnf(unittest.TestCase): self.assertEqual(result, udp_replay_approx_vnf.collect_kpi()) @mock.patch(SSH_HELPER) - def test_get_stats(self, ssh, _): + def test_get_stats(self, ssh, *args): mock_ssh(ssh) udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0) @@ -376,7 +374,7 @@ class TestUdpReplayApproxVnf(unittest.TestCase): @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context") @mock.patch(SSH_HELPER) - def test__build_config(self, ssh, mock_context, *_): + def test__build_config(self, ssh, mock_context, *args): mock_ssh(ssh) udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0) @@ -397,7 +395,7 @@ class TestUdpReplayApproxVnf(unittest.TestCase): @mock.patch('yardstick.network_services.vnf_generic.vnf.udp_replay.open') @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context") @mock.patch(SSH_HELPER) - def test__build_pipeline_kwargs(self, ssh, mock_context, *_): + def test__build_pipeline_kwargs(self, ssh, mock_context, *args): mock_ssh(ssh) udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0) udp_replay_approx_vnf.nfvi_context = mock_context @@ -420,7 +418,7 @@ class TestUdpReplayApproxVnf(unittest.TestCase): }) @mock.patch(SSH_HELPER) - def test_run_udp_replay(self, ssh, _): + def test_run_udp_replay(self, ssh, *args): mock_ssh(ssh) udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0) @@ -434,11 +432,9 @@ class TestUdpReplayApproxVnf(unittest.TestCase): @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context") @mock.patch(SSH_HELPER) - def test_instantiate(self, ssh, *_): + def test_instantiate(self, ssh, *args): mock_ssh(ssh) - resource = mock.Mock(autospec=ResourceProfile) - udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0) udp_replay_approx_vnf.q_out.put("Replay>") udp_replay_approx_vnf.WAIT_TIME = 0 @@ -456,7 +452,7 @@ class TestUdpReplayApproxVnf(unittest.TestCase): @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context") @mock.patch('yardstick.ssh.SSH') @mock.patch(SSH_HELPER) - def test_instantiate_panic(self, ssh, resource_ssh, *_): + def test_instantiate_panic(self, *args): udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0) udp_replay_approx_vnf.WAIT_TIME = 0 udp_replay_approx_vnf.q_out.put("some text PANIC some text") @@ -467,15 +463,9 @@ class TestUdpReplayApproxVnf(unittest.TestCase): with self.assertRaises(RuntimeError): udp_replay_approx_vnf.wait_for_instantiate() - def test_scale(self, _): - udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0) - flavor = "" - - self.assertRaises(NotImplementedError, udp_replay_approx_vnf.scale, flavor) - @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch(SSH_HELPER) - def test_terminate(self, ssh, mock_time, _): + def test_terminate(self, ssh, *args): mock_ssh(ssh) udp_replay_approx_vnf = UdpReplayApproxVnf(NAME, self.VNFD_0) @@ -484,6 +474,3 @@ class TestUdpReplayApproxVnf(unittest.TestCase): udp_replay_approx_vnf.used_drivers = {"01:01.0": "i40e", "01:01.1": "i40e"} udp_replay_approx_vnf.dpdk_nic_bind = "dpdk_nic_bind.py" self.assertEqual(None, udp_replay_approx_vnf.terminate()) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/unit/network_services/vnf_generic/vnf/test_vfw_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_vfw_vnf.py index 958099a03..d128db0b4 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_vfw_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_vfw_vnf.py @@ -15,8 +15,6 @@ # limitations under the License. # -from __future__ import absolute_import - import unittest import mock import os @@ -32,10 +30,10 @@ if stl_patch: from yardstick.network_services.vnf_generic.vnf.vfw_vnf import FWApproxVnf from yardstick.network_services.nfvi.resource import ResourceProfile + TEST_FILE_YAML = 'nsb_test_case.yaml' SSH_HELPER = 'yardstick.network_services.vnf_generic.vnf.sample_vnf.VnfSshHelper' - name = 'vnf__1' @@ -239,7 +237,7 @@ class TestFWApproxVnf(unittest.TestCase): 'password': 'r00t', 'VNF model': 'vfw_vnf.yaml'}}} - def test___init__(self, mock_process): + def test___init__(self, *args): vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] vfw_approx_vnf = FWApproxVnf(name, vnfd) self.assertIsNone(vfw_approx_vnf._vnf_process) @@ -260,7 +258,7 @@ pipeline> @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch(SSH_HELPER) - def test_collect_kpi(self, ssh, mock_time, mock_process): + def test_collect_kpi(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -282,7 +280,7 @@ pipeline> @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch(SSH_HELPER) - def test_vnf_execute_command(self, ssh, mock_time, mock_process): + def test_vnf_execute_command(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -294,7 +292,7 @@ pipeline> self.assertEqual(vfw_approx_vnf.vnf_execute(cmd), "") @mock.patch(SSH_HELPER) - def test_get_stats(self, ssh, mock_process): + def test_get_stats(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -314,7 +312,7 @@ pipeline> @mock.patch("yardstick.network_services.vnf_generic.vnf.vfw_vnf.eval") @mock.patch("yardstick.network_services.vnf_generic.vnf.vfw_vnf.open") @mock.patch(SSH_HELPER) - def test_run_vfw(self, ssh, mock_open, mock_eval, mock_hex, mock_process): + def test_run_vfw(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -337,7 +335,7 @@ pipeline> @mock.patch("yardstick.network_services.vnf_generic.vnf.vfw_vnf.YangModel") @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.Context") @mock.patch(SSH_HELPER) - def test_instantiate(self, ssh, mock_context, mock_yang, mock_find, mock_process): + def test_instantiate(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -351,16 +349,9 @@ pipeline> self.scenario_cfg.update({"nodes": {"vnf__1": ""}}) self.assertIsNone(vfw_approx_vnf.instantiate(self.scenario_cfg, self.context_cfg)) - def test_scale(self, mock_process): - vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] - vfw_approx_vnf = FWApproxVnf(name, vnfd) - flavor = "" - with self.assertRaises(NotImplementedError): - vfw_approx_vnf.scale(flavor) - @mock.patch("yardstick.network_services.vnf_generic.vnf.sample_vnf.time") @mock.patch(SSH_HELPER) - def test_terminate(self, ssh, mock_time, mock_process): + def test_terminate(self, ssh, *args): mock_ssh(ssh) vnfd = self.VNFD['vnfd:vnfd-catalog']['vnfd'][0] @@ -372,6 +363,3 @@ pipeline> vfw_approx_vnf.dpdk_nic_bind = "dpdk_nic_bind.py" vfw_approx_vnf._resource_collect_stop = mock.Mock() self.assertIsNone(vfw_approx_vnf.terminate()) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/unit/network_services/vnf_generic/vnf/test_vpe_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_vpe_vnf.py index 4103d7825..55cd4d2e8 100644 --- a/tests/unit/network_services/vnf_generic/vnf/test_vpe_vnf.py +++ b/tests/unit/network_services/vnf_generic/vnf/test_vpe_vnf.py @@ -15,15 +15,16 @@ # limitations under the License. # -from __future__ import absolute_import -import six.moves.configparser as configparser - -import os -import unittest import mock from multiprocessing import Process, Queue +import os +import six.moves.configparser as configparser +import time +import unittest from tests.unit import STL_MOCKS +from tests.unit.network_services.vnf_generic.vnf.test_base import FileAbsPath +from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh from yardstick.network_services.vnf_generic.vnf.base import QueueFileWrapper from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper @@ -40,9 +41,6 @@ if stl_patch: from yardstick.network_services.vnf_generic.vnf.vpe_vnf import \ VpeApproxVnf, VpeApproxSetupEnvHelper -from tests.unit.network_services.vnf_generic.vnf.test_base import FileAbsPath -from tests.unit.network_services.vnf_generic.vnf.test_base import mock_ssh - TEST_FILE_YAML = 'nsb_test_case.yaml' @@ -227,28 +225,6 @@ class TestConfigCreate(unittest.TestCase): self.assertNotEqual(result, '') def test_create_vpe_config(self): - uplink_ports = [ - { - 'index': 0, - 'dpdk_port_num': 1, - 'peer_intf': { - 'dpdk_port_num': 2, - 'index': 3, - }, - }, - ] - - downlink_ports = [ - { - 'index': 2, - 'dpdk_port_num': 3, - 'peer_intf': { - 'dpdk_port_num': 0, - 'index': 1, - }, - }, - ] - vnfd_helper = VnfdHelper(self.VNFD_0) config_create = ConfigCreate(vnfd_helper, 23) config_create.downlink_ports = ['xe1'] @@ -260,7 +236,6 @@ class TestConfigCreate(unittest.TestCase): os.system("git checkout -- %s" % vnf_cfg) -@mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.time') class TestVpeApproxVnf(unittest.TestCase): VNFD_0 = { @@ -556,12 +531,15 @@ class TestVpeApproxVnf(unittest.TestCase): }, } - def test___init__(self, _): + def setUp(self): + self.mock_sleep = mock.patch.object(time, 'sleep').start() + + def test___init__(self): vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0) self.assertIsNone(vpe_approx_vnf._vnf_process) @mock.patch(SSH_HELPER) - def test_collect_kpi_sa_not_running(self, ssh, _): + def test_collect_kpi_sa_not_running(self, ssh): mock_ssh(ssh) resource = mock.Mock(autospec=ResourceProfile) @@ -585,7 +563,7 @@ class TestVpeApproxVnf(unittest.TestCase): self.assertEqual(vpe_approx_vnf.collect_kpi(), expected) @mock.patch(SSH_HELPER) - def test_collect_kpi_sa_running(self, ssh, _): + def test_collect_kpi_sa_running(self, ssh): mock_ssh(ssh) resource = mock.Mock(autospec=ResourceProfile) @@ -608,7 +586,7 @@ class TestVpeApproxVnf(unittest.TestCase): self.assertEqual(vpe_approx_vnf.collect_kpi(), expected) @mock.patch(SSH_HELPER) - def test_vnf_execute(self, ssh, _): + def test_vnf_execute(self, ssh): mock_ssh(ssh) vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0) vpe_approx_vnf.q_in = mock.MagicMock() @@ -617,7 +595,7 @@ class TestVpeApproxVnf(unittest.TestCase): self.assertEqual(vpe_approx_vnf.vnf_execute("quit", 0), '') @mock.patch(SSH_HELPER) - def test_run_vpe(self, ssh, _): + def test_run_vpe(self, ssh): mock_ssh(ssh) vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0) @@ -651,7 +629,7 @@ class TestVpeApproxVnf(unittest.TestCase): @mock.patch("yardstick.network_services.vnf_generic.vnf.vpe_vnf.ConfigCreate") @mock.patch("yardstick.network_services.vnf_generic.vnf.vpe_vnf.open") @mock.patch(SSH_HELPER) - def test_build_config(self, mock_mul, mock_context, mock_config, mock_open, ssh, _): + def test_build_config(self, ssh, *args): mock_ssh(ssh) vpe_approx_vnf = VpeApproxSetupEnvHelper(mock.MagicMock(), mock.MagicMock, mock.MagicMock) @@ -684,7 +662,7 @@ class TestVpeApproxVnf(unittest.TestCase): self.assertIsNotNone(vpe_approx_vnf.build_config()) @mock.patch(SSH_HELPER) - def test_wait_for_instantiate(self, ssh, _): + def test_wait_for_instantiate(self, ssh): mock_ssh(ssh) mock_process = mock.Mock(autospec=Process) @@ -707,7 +685,7 @@ class TestVpeApproxVnf(unittest.TestCase): self.assertEqual(vpe_approx_vnf.wait_for_instantiate(), 432) @mock.patch(SSH_HELPER) - def test_wait_for_instantiate_fragmented(self, ssh, _): + def test_wait_for_instantiate_fragmented(self, ssh): mock_ssh(ssh) mock_process = mock.Mock(autospec=Process) @@ -730,7 +708,7 @@ class TestVpeApproxVnf(unittest.TestCase): self.assertEqual(vpe_approx_vnf.wait_for_instantiate(), 432) @mock.patch(SSH_HELPER) - def test_wait_for_instantiate_crash(self, ssh, _): + def test_wait_for_instantiate_crash(self, ssh): mock_ssh(ssh, exec_result=(1, "", "")) mock_process = mock.Mock(autospec=Process) @@ -749,7 +727,7 @@ class TestVpeApproxVnf(unittest.TestCase): self.assertIn('VNF process died', str(raised.exception)) @mock.patch(SSH_HELPER) - def test_wait_for_instantiate_panic(self, ssh, _): + def test_wait_for_instantiate_panic(self, ssh): mock_ssh(ssh, exec_result=(1, "", "")) mock_process = mock.Mock(autospec=Process) @@ -769,7 +747,7 @@ class TestVpeApproxVnf(unittest.TestCase): self.assertIn('Error starting', str(raised.exception)) @mock.patch(SSH_HELPER) - def test_wait_for_instantiate_panic_fragmented(self, ssh, _): + def test_wait_for_instantiate_panic_fragmented(self, ssh): mock_ssh(ssh, exec_result=(1, "", "")) mock_process = mock.Mock(autospec=Process) @@ -793,13 +771,8 @@ class TestVpeApproxVnf(unittest.TestCase): self.assertIn('Error starting', str(raised.exception)) - def test_scale(self, _): - vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0) - with self.assertRaises(NotImplementedError): - vpe_approx_vnf.scale('') - @mock.patch(SSH_HELPER) - def test_terminate(self, ssh, _): + def test_terminate(self, ssh): mock_ssh(ssh) vpe_approx_vnf = VpeApproxVnf(NAME, self.VNFD_0) @@ -808,7 +781,3 @@ class TestVpeApproxVnf(unittest.TestCase): vpe_approx_vnf.resource_helper = mock.MagicMock() self.assertIsNone(vpe_approx_vnf.terminate()) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/unit/test_ssh.py b/tests/unit/test_ssh.py index b298c745b..88699fd85 100644 --- a/tests/unit/test_ssh.py +++ b/tests/unit/test_ssh.py @@ -546,6 +546,15 @@ class TestAutoConnectSSH(unittest.TestCase): with mock_scp_client_type() as mock_scp_client: self.assertEqual(mock_scp_client.put.call_count, 1) + @mock.patch('yardstick.ssh.SCPClient') + def test_get(self, mock_scp_client_type): + auto_connect_ssh = AutoConnectSSH('user1', 'host1') + auto_connect_ssh._client = mock.Mock() + + auto_connect_ssh.get('a', 'z') + with mock_scp_client_type() as mock_scp_client: + self.assertEqual(mock_scp_client.get.call_count, 1) + def test_put_file(self): auto_connect_ssh = AutoConnectSSH('user1', 'host1') auto_connect_ssh._client = mock.Mock() diff --git a/yardstick/benchmark/scenarios/compute/spec_cpu_for_vm.py b/yardstick/benchmark/scenarios/compute/spec_cpu_for_vm.py new file mode 100644 index 000000000..36489b132 --- /dev/null +++ b/yardstick/benchmark/scenarios/compute/spec_cpu_for_vm.py @@ -0,0 +1,170 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd 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 +############################################################################## +from __future__ import absolute_import + +import logging +import pkg_resources +import os + +import yardstick.ssh as ssh +from yardstick.benchmark.scenarios import base +from yardstick.common.constants import YARDSTICK_ROOT_PATH + +LOG = logging.getLogger(__name__) + + +class SpecCPUforVM(base.Scenario): + """Spec CPU2006 benchmark for Virtual Machine + + Parameters + benchmark_subset - Specifies a subset of SPEC CPU2006 benchmarks to run + type: string + unit: na + default: na + + SPECint_benchmark - A SPECint benchmark to run + type: string + unit: na + default: na + + SPECfp_benchmark - A SPECfp benchmark to run + type: string + unit: na + default: na + + output_format - Desired report format + type: string + unit: na + default: na + + runspec_config - SPEC CPU2006 config file provided to the runspec binary + type: string + unit: na + default: "Example-linux64-amd64-gcc43+.cfg" + + runspec_iterations - The number of benchmark iterations to execute. + For a reportable run, must be 3. + type: int + unit: na + default: na + + runspec_tune - Tuning to use (base, peak, or all). For a reportable run, must be either + base or all. Reportable runs do base first, then (optionally) peak. + type: string + unit: na + default: na + + runspec_size - Size of input data to run (test, train, or ref). Reportable runs ensure + that your binaries can produce correct results with the test and train + workloads. + type: string + unit: na + default: na + """ + __scenario_type__ = "SpecCPU2006_for_VM" + CPU2006_ISO = "cpu2006-1.2.iso" + CPU2006_DIR = "~/cpu2006" + CPU2006_RESULT_FILE = os.path.join(CPU2006_DIR, "result/CINT2006.001.ref.txt") + + def __init__(self, scenario_cfg, context_cfg): + self.scenario_cfg = scenario_cfg + self.context_cfg = context_cfg + self.setup_done = False + self.options = self.scenario_cfg['options'] + + def setup(self): + """scenario setup""" + host = self.context_cfg['host'] + LOG.info("user:%s, host:%s", host['user'], host['ip']) + self.client = ssh.SSH.from_node(host, defaults={"user": "ubuntu"}) + self.client.wait(timeout=600) + + spec_cpu_iso = os.path.join(YARDSTICK_ROOT_PATH, + "yardstick/resources/files/", + self.CPU2006_ISO) + + self.client.put(spec_cpu_iso, "~/cpu2006-1.2.iso") + self.client.execute("sudo mount -t iso9660 -o ro,exec ~/cpu2006-1.2.iso /mnt") + self.client.execute("/mnt/install.sh -fd ~/cpu2006") + + if "runspec_config" in self.options: + self.runspec_config = self.options["runspec_config"] + + self.runspec_config_file = pkg_resources.resource_filename( + "yardstick.resources", 'files/' + self.runspec_config) + + # copy SPEC CPU2006 config file to host if given + cfg_path = os.path.join(self.CPU2006_DIR, + 'config/yardstick_spec_cpu2006.cfg') + self.client._put_file_shell(self.runspec_config_file, cfg_path) + else: + self.runspec_config = "Example-linux64-amd64-gcc43+.cfg" + + self.setup_done = True + + def run(self, result): + """execute the benchmark""" + + if not self.setup_done: + self.setup() + + cmd = "cd %s && . ./shrc && runspec --config %s" % ( + self.CPU2006_DIR, self.runspec_config) + cmd_args = "" + + if "rate" in self.options: + cmd_args += " --rate %s" % self.options["runspec_rate"] + + if "output_format" in self.options: + cmd_args += " --output_format %s" % self.options["output_format"] + + if "runspec_tune" in self.options: + cmd_args += " --tune %s" % self.options["runspec_tune"] + + benchmark_subset = self.options.get('benchmark_subset', None) + specint_benchmark = self.options.get('SPECint_benchmark', None) + specfp_benchmark = self.options.get('SPECfp_benchmark', None) + + if benchmark_subset: + cmd_args += " %s" % benchmark_subset + else: + cmd_args += " --noreportable" + + if "runspec_iterations" in self.options: + cmd_args += " --iterations %s" % self.options["runspec_iterations"] + + if "runspec_size" in self.options: + cmd_args += " --size %s" % self.options["runspec_size"] + + if specint_benchmark: + cmd_args += " %s" % specint_benchmark + + if specfp_benchmark: + cmd_args += " %s" % specfp_benchmark + + cmd += "%s" % cmd_args + + LOG.debug("Executing command: %s", cmd) + status, stdout, stderr = self.client.execute(cmd, timeout=86400) + if status: + raise RuntimeError(stderr) + + cmd = "cat %s" % self.CPU2006_RESULT_FILE + LOG.debug("Executing command: %s", cmd) + status, stdout, stderr = self.client.execute(cmd, timeout=30) + if status: + raise RuntimeError(stderr) + if stdout: + LOG.info("SPEC CPU2006 result is:\n%s", stdout) + + result.update({"SPEC_CPU_result": stdout}) + # fetch SPEC CPU2006 result files + self.client.get('~/cpu2006/result', '/tmp/') + LOG.info('SPEC CPU2006 benchmark completed, please find benchmark reports \ + at /tmp/result directory') diff --git a/yardstick/common/exceptions.py b/yardstick/common/exceptions.py new file mode 100644 index 000000000..4780822a4 --- /dev/null +++ b/yardstick/common/exceptions.py @@ -0,0 +1,59 @@ +# Copyright (c) 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. + +from oslo_utils import excutils + + +class ProcessExecutionError(RuntimeError): + def __init__(self, message, returncode): + super(ProcessExecutionError, self).__init__(message) + self.returncode = returncode + + +class YardstickException(Exception): + """Base Yardstick Exception. + + To correctly use this class, inherit from it and define + a 'message' property. That message will get printf'd + with the keyword arguments provided to the constructor. + + Based on NeutronException class. + """ + message = "An unknown exception occurred." + + def __init__(self, **kwargs): + try: + super(YardstickException, self).__init__(self.message % kwargs) + self.msg = self.message % kwargs + except Exception: # pylint: disable=broad-except + with excutils.save_and_reraise_exception() as ctxt: + if not self.use_fatal_exceptions(): + ctxt.reraise = False + # at least get the core message out if something happened + super(YardstickException, self).__init__(self.message) + + def __str__(self): + return self.msg + + def use_fatal_exceptions(self): + """Is the instance using fatal exceptions. + + :returns: Always returns False. + """ + return False + + +class FunctionNotImplemented(YardstickException): + message = ('The function "%(function_name)s" is not implemented in ' + '"%(class_name)" class.') diff --git a/yardstick/common/process.py b/yardstick/common/process.py index 812ddea94..ede6cddac 100644 --- a/yardstick/common/process.py +++ b/yardstick/common/process.py @@ -11,10 +11,19 @@ # 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 logging import multiprocessing +import signal +import subprocess +import time import os +from oslo_utils import encodeutils + +from yardstick.common import exceptions +from yardstick.common import utils + LOG = logging.getLogger(__name__) @@ -45,3 +54,85 @@ def terminate_children(timeout=3): for child in active_children: LOG.debug("%s %s %s, after terminate child: %s %s", current_proccess.name, current_proccess.pid, os.getpid(), child, child.pid) + + +def _additional_env_args(additional_env): + """Build arguments for adding additional environment vars with env""" + if additional_env is None: + return [] + return ['env'] + ['%s=%s' % pair for pair in additional_env.items()] + + +def _subprocess_setup(): + # Python installs a SIGPIPE handler by default. This is usually not what + # non-Python subprocesses expect. + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + + +def subprocess_popen(args, stdin=None, stdout=None, stderr=None, shell=False, + env=None, preexec_fn=_subprocess_setup, close_fds=True): + return subprocess.Popen(args, shell=shell, stdin=stdin, stdout=stdout, + stderr=stderr, preexec_fn=preexec_fn, + close_fds=close_fds, env=env) + + +def create_process(cmd, run_as_root=False, additional_env=None): + """Create a process object for the given command. + + The return value will be a tuple of the process object and the + list of command arguments used to create it. + """ + if not isinstance(cmd, list): + cmd = [cmd] + cmd = list(map(str, _additional_env_args(additional_env) + cmd)) + if run_as_root: + # NOTE(ralonsoh): to handle a command executed as root, using + # a root wrapper, instead of using "sudo". + pass + LOG.debug("Running command: %s", cmd) + obj = subprocess_popen(cmd, shell=False, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + return obj, cmd + + +def execute(cmd, process_input=None, additional_env=None, + check_exit_code=True, return_stderr=False, log_fail_as_error=True, + extra_ok_codes=None, run_as_root=False): + try: + if process_input is not None: + _process_input = encodeutils.to_utf8(process_input) + else: + _process_input = None + + # NOTE(ralonsoh): to handle the execution of a command as root, + # using a root wrapper, instead of using "sudo". + obj, cmd = create_process(cmd, run_as_root=run_as_root, + additional_env=additional_env) + _stdout, _stderr = obj.communicate(_process_input) + returncode = obj.returncode + obj.stdin.close() + _stdout = utils.safe_decode_utf8(_stdout) + _stderr = utils.safe_decode_utf8(_stderr) + + extra_ok_codes = extra_ok_codes or [] + if returncode and returncode not in extra_ok_codes: + msg = ("Exit code: %(returncode)d; " + "Stdin: %(stdin)s; " + "Stdout: %(stdout)s; " + "Stderr: %(stderr)s") % {'returncode': returncode, + 'stdin': process_input or '', + 'stdout': _stdout, + 'stderr': _stderr} + if log_fail_as_error: + LOG.error(msg) + if check_exit_code: + raise exceptions.ProcessExecutionError(msg, + returncode=returncode) + + finally: + # This appears to be necessary in order for the subprocess to clean up + # something between call; without it, the second process hangs when two + # execute calls are made in a row. + time.sleep(0) + + return (_stdout, _stderr) if return_stderr else _stdout diff --git a/yardstick/common/utils.py b/yardstick/common/utils.py index 51f6e1360..82e20bec7 100644 --- a/yardstick/common/utils.py +++ b/yardstick/common/utils.py @@ -76,7 +76,7 @@ def import_modules_from_package(package): """ yardstick_root = os.path.dirname(os.path.dirname(yardstick.__file__)) path = os.path.join(yardstick_root, *package.split(".")) - for root, dirs, files in os.walk(path): + for root, _, files in os.walk(path): matches = (filename for filename in files if filename.endswith(".py") and not filename.startswith("__")) new_package = os.path.relpath(root, yardstick_root).replace(os.sep, ".") @@ -251,10 +251,10 @@ def set_dict_value(dic, keys, value): def get_free_port(ip): with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: - while True: + port = random.randint(5000, 10000) + while s.connect_ex((ip, port)) == 0: port = random.randint(5000, 10000) - if s.connect_ex((ip, port)) != 0: - return port + return port def mac_address_to_hex_list(mac): @@ -350,10 +350,13 @@ def config_to_dict(config): def validate_non_string_sequence(value, default=None, raise_exc=None): + # NOTE(ralonsoh): refactor this function to check if raise_exc is an + # Exception. Remove duplicate code, this function is duplicated in this + # repository. if isinstance(value, collections.Sequence) and not isinstance(value, six.string_types): return value if raise_exc: - raise raise_exc + raise raise_exc # pylint: disable=raising-bad-type return default @@ -365,6 +368,13 @@ def join_non_strings(separator, *non_strings): return str(separator).join(str(non_string) for non_string in non_strings) +def safe_decode_utf8(s): + """Safe decode a str from UTF""" + if six.PY3 and isinstance(s, bytes): + return s.decode('utf-8', 'surrogateescape') + return s + + class ErrorClass(object): def __init__(self, *args, **kwargs): diff --git a/yardstick/network_services/vnf_generic/vnf/acl_vnf.py b/yardstick/network_services/vnf_generic/vnf/acl_vnf.py index 3ba38dec2..1390dd02e 100644 --- a/yardstick/network_services/vnf_generic/vnf/acl_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/acl_vnf.py @@ -61,9 +61,6 @@ class AclApproxVnf(SampleVNF): super(AclApproxVnf, self).__init__(name, vnfd, setup_env_helper_type, resource_helper_type) self.acl_rules = None - def scale(self, flavor=""): - raise NotImplementedError - def _start_vnf(self): yang_model_path = find_relative_file(self.scenario_helper.options['rules'], self.scenario_helper.task_path) diff --git a/yardstick/network_services/vnf_generic/vnf/base.py b/yardstick/network_services/vnf_generic/vnf/base.py index 8ed754dce..a776b0989 100644 --- a/yardstick/network_services/vnf_generic/vnf/base.py +++ b/yardstick/network_services/vnf_generic/vnf/base.py @@ -138,76 +138,62 @@ class VnfdHelper(dict): yield port_name, port_num -class VNFObject(object): +@six.add_metaclass(abc.ABCMeta) +class GenericVNF(object): + """Class providing file-like API for generic VNF implementation + + Currently the only class implementing this interface is + yardstick/network_services/vnf_generic/vnf/sample_vnf:SampleVNF. + """ # centralize network naming convention UPLINK = PortPairs.UPLINK DOWNLINK = PortPairs.DOWNLINK def __init__(self, name, vnfd): - super(VNFObject, self).__init__() self.name = name - self.vnfd_helper = VnfdHelper(vnfd) # fixme: parse this into a structure - - -class GenericVNF(VNFObject): - - """ Class providing file-like API for generic VNF implementation """ - def __init__(self, name, vnfd): - super(GenericVNF, self).__init__(name, vnfd) + self.vnfd_helper = VnfdHelper(vnfd) # List of statistics we can obtain from this VNF # - ETSI MANO 6.3.1.1 monitoring_parameter - self.kpi = self._get_kpi_definition() + self.kpi = self.vnfd_helper.kpi # Standard dictionary containing params like thread no, buffer size etc self.config = {} self.runs_traffic = False - def _get_kpi_definition(self): - """ Get list of KPIs defined in VNFD - - :param vnfd: - :return: list of KPIs, e.g. ['throughput', 'latency'] - """ - return self.vnfd_helper.kpi - + @abc.abstractmethod def instantiate(self, scenario_cfg, context_cfg): - """ Prepare VNF for operation and start the VNF process/VM + """Prepare VNF for operation and start the VNF process/VM - :param scenario_cfg: - :param context_cfg: + :param scenario_cfg: Scenario config + :param context_cfg: Context config :return: True/False """ - raise NotImplementedError() + @abc.abstractmethod def wait_for_instantiate(self): - """ Wait for VNF to start + """Wait for VNF to start :return: True/False """ - raise NotImplementedError() + @abc.abstractmethod def terminate(self): - """ Kill all VNF processes - - :return: - """ - raise NotImplementedError() + """Kill all VNF processes""" + @abc.abstractmethod def scale(self, flavor=""): - """ + """rest - :param flavor: + :param flavor: Name of the flavor. :return: """ - raise NotImplementedError() + @abc.abstractmethod def collect_kpi(self): - """This method should return a dictionary containing the - selected KPI at a given point of time. + """Return a dict containing the selected KPI at a given point of time :return: {"kpi": value, "kpi2": value} """ - raise NotImplementedError() @six.add_metaclass(abc.ABCMeta) diff --git a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py index ba066333d..285ead3b6 100644 --- a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py +++ b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py @@ -11,7 +11,6 @@ # 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. -from __future__ import absolute_import import array import io @@ -363,9 +362,9 @@ class ProxSocketHelper(object): """ send data to the remote instance """ LOG.debug("Sending data to socket: [%s]", to_send.rstrip('\n')) try: - # TODO: sendall will block, we need a timeout + # NOTE: sendall will block, we need a timeout self._sock.sendall(to_send.encode('utf-8')) - except: + except: # pylint: disable=bare-except pass def get_packet_dump(self): @@ -539,7 +538,7 @@ class ProxSocketHelper(object): finally: container['end_tot'] = end = self.get_all_tot_stats() - container['delta'] = TotStatsTuple(end - start for start, end in zip(start, end)) + container['delta'] = TotStatsTuple(e - s for s, e in zip(start, end)) def tot_stats(self): """Get the total statistics from the remote system""" @@ -637,13 +636,6 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): raise KeyError(template.format(section_key, section_name)) return result - def _build_pipeline_kwargs(self): - tool_path = self.ssh_helper.provision_tool(tool_file=self.APP_NAME) - self.pipeline_kwargs = { - 'tool_path': tool_path, - 'tool_dir': os.path.dirname(tool_path), - } - def copy_to_target(self, config_file_path, prox_file): remote_path = os.path.join("/tmp", prox_file) self.ssh_helper.put(config_file_path, remote_path) @@ -685,14 +677,13 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): if port_section_name != section_name: continue - for index, section_data in enumerate(section): + for section_data in section: if section_data[0] == "mac": section_data[1] = "hardware" # search for dst mac for _, section in sections: - # for index, (item_key, item_val) in enumerate(section): - for index, section_data in enumerate(section): + for section_data in section: item_key, item_val = section_data if item_val.startswith("@@dst_mac"): tx_port_iter = re.finditer(r'\d+', item_val) @@ -713,14 +704,14 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): return sections for section_name, section in sections: - for index, section_data in enumerate(section): + for section_data in section: try: if section_data[0].startswith("dofile"): section_data[0] = self._insert_additional_file(section_data[0]) if section_data[1].startswith("dofile"): section_data[1] = self._insert_additional_file(section_data[1]) - except: + except: # pylint: disable=bare-except pass return sections @@ -753,9 +744,9 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): a custom method """ out = [] - for i, (section_name, section) in enumerate(prox_config): + for (section_name, section) in prox_config: out.append("[{}]".format(section_name)) - for index, item in enumerate(section): + for item in section: key, value = item if key == "__name__": continue @@ -816,7 +807,7 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): self.lua = self.generate_prox_lua_file() if len(self.lua) > 0: self.upload_prox_lua("parameters.lua", self.lua) - except: + except: # pylint: disable=bare-except pass prox_files = options.get('prox_files', []) @@ -837,17 +828,20 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): self.build_config_file() options = self.scenario_helper.options - prox_args = options['prox_args'] - LOG.info("Provision and start the %s", self.APP_NAME) - self._build_pipeline_kwargs() - self.pipeline_kwargs["args"] = " ".join( - " ".join([k, v if v else ""]) for k, v in prox_args.items()) - self.pipeline_kwargs["cfg_file"] = self.remote_path + tool_path = self.ssh_helper.join_bin_path(self.APP_NAME) + + self.pipeline_kwargs = { + 'tool_path': tool_path, + 'tool_dir': os.path.dirname(tool_path), + 'cfg_file': self.remote_path, + 'args': ' '.join(' '.join([str(k), str(v) if v else '']) + for k, v in prox_args.items()) + } - cmd_template = "sudo bash -c 'cd {tool_dir}; {tool_path} -o cli {args} -f {cfg_file} '" - prox_cmd = cmd_template.format(**self.pipeline_kwargs) - return prox_cmd + cmd_template = ("sudo bash -c 'cd {tool_dir}; {tool_path} -o cli " + "{args} -f {cfg_file} '") + return cmd_template.format(**self.pipeline_kwargs) # this might be bad, sometimes we want regular ResourceHelper methods, like collect_kpi @@ -1057,7 +1051,7 @@ class ProxDataHelper(object): self.tsc_hz = float(self.sut.hz()) def line_rate_to_pps(self): - # FIXME Don't hardcode 10Gb/s + # NOTE: to fix, don't hardcode 10Gb/s return self.port_count * TEN_GIGABIT / BITS_PER_BYTE / (self.pkt_size + 20) @@ -1658,7 +1652,7 @@ class ProxlwAFTRProfileHelper(ProxProfileHelper): tun_ports = [] inet_ports = [] - re_port = re.compile('port (\d+)') + re_port = re.compile(r'port (\d+)') for section_name, section in self.resource_helper.setup_helper.prox_config_data: match = re_port.search(section_name) if not match: diff --git a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py index 20e5895ee..5eeb6c889 100644 --- a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py @@ -28,6 +28,7 @@ from six.moves import cStringIO from yardstick.benchmark.contexts.base import Context from yardstick.benchmark.scenarios.networking.vnf_generic import find_relative_file +from yardstick.common import exceptions as y_exceptions from yardstick.common.process import check_if_process_failed from yardstick.network_services.helpers.samplevnf_helper import PortPairs from yardstick.network_services.helpers.samplevnf_helper import MultiPortConfig @@ -308,7 +309,7 @@ class DpdkVnfSetupEnvHelper(SetupEnvHelper): if vpci == v['virtual-interface']['vpci']) # force to int intf['virtual-interface']['dpdk_port_num'] = int(dpdk_port_num) - except: + except: # pylint: disable=bare-except pass time.sleep(2) @@ -472,6 +473,11 @@ class ClientResourceHelper(ResourceHelper): self.client.clear_stats(ports=ports) def start(self, ports=None, *args, **kwargs): + # pylint: disable=keyword-arg-before-vararg + # NOTE(ralonsoh): defining keyworded arguments before variable + # positional arguments is a bug. This function definition doesn't work + # in Python 2, although it works in Python 3. Reference: + # https://www.python.org/dev/peps/pep-3102/ if ports is None: ports = self.all_ports self.client.start(ports=ports, *args, **kwargs) @@ -480,8 +486,8 @@ class ClientResourceHelper(ResourceHelper): if not self._queue.empty(): kpi = self._queue.get() self._result.update(kpi) - LOG.debug("Got KPIs from _queue for {0} {1}".format( - self.scenario_helper.name, self.RESOURCE_WORD)) + LOG.debug('Got KPIs from _queue for %s %s', + self.scenario_helper.name, self.RESOURCE_WORD) return self._result def _connect(self, client=None): @@ -670,7 +676,7 @@ class SampleVNF(GenericVNF): self.pipeline_kwargs = {} self.uplink_ports = None self.downlink_ports = None - # TODO(esm): make QueueFileWrapper invert-able so that we + # NOTE(esm): make QueueFileWrapper invert-able so that we # never have to manage the queues self.q_in = Queue() self.q_out = Queue() @@ -751,7 +757,7 @@ class SampleVNF(GenericVNF): if not self._vnf_process.is_alive(): raise RuntimeError("%s VNF process died." % self.APP_NAME) - # TODO(esm): move to QueueFileWrapper + # NOTE(esm): move to QueueFileWrapper while self.q_out.qsize() > 0: buf.append(self.q_out.get()) message = ''.join(buf) @@ -821,12 +827,12 @@ class SampleVNF(GenericVNF): self._vnf_process.terminate() # no terminate children here because we share processes with tg - def get_stats(self, *args, **kwargs): - """ - Method for checking the statistics + def get_stats(self, *args, **kwargs): # pylint: disable=unused-argument + """Method for checking the statistics + + This method could be overridden in children classes. - :return: - VNF statistics + :return: VNF statistics """ cmd = 'p {0} stats'.format(self.APP_WORD) out = self.vnf_execute(cmd) @@ -849,6 +855,11 @@ class SampleVNF(GenericVNF): LOG.debug("%s collect KPIs %s", self.APP_NAME, result) return result + def scale(self, flavor=""): + """The SampleVNF base class doesn't provide the 'scale' feature""" + raise y_exceptions.FunctionNotImplemented( + function_name='scale', class_name='SampleVNFTrafficGen') + class SampleVNFTrafficGen(GenericTrafficGen): """ Class providing file-like API for generic traffic generator """ @@ -964,3 +975,8 @@ class SampleVNFTrafficGen(GenericTrafficGen): self._tg_process.join(PROCESS_JOIN_TIMEOUT) self._tg_process.terminate() # no terminate children here because we share processes with vnf + + def scale(self, flavor=""): + """A traffic generator VFN doesn't provide the 'scale' feature""" + raise y_exceptions.FunctionNotImplemented( + function_name='scale', class_name='SampleVNFTrafficGen') diff --git a/yardstick/network_services/vnf_generic/vnf/tg_ping.py b/yardstick/network_services/vnf_generic/vnf/tg_ping.py index 30a917862..a989543f5 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_ping.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_ping.py @@ -113,10 +113,6 @@ class PingTrafficGen(SampleVNFTrafficGen): resource_helper_type) self._result = {} - def scale(self, flavor=""): - """ scale vnf-based on flavor input """ - pass - def _check_status(self): return self._tg_process.is_alive() @@ -126,11 +122,10 @@ class PingTrafficGen(SampleVNFTrafficGen): "packets_received": 0, "rtt": 0, } + self.setup_helper.setup_vnf_environment() intf = self.vnfd_helper.interfaces[0]["virtual-interface"] self.resource_helper.cmd_kwargs = { 'target_ip': IPv4Interface(intf["dst_ip"]).ip.exploded, 'local_ip': IPv4Interface(intf["local_ip"]).ip.exploded, 'local_if_name': intf["local_iface_name"].split('/')[0], } - - self.setup_helper.setup_vnf_environment() diff --git a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py index a8b19cfba..630c8b9c0 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py @@ -174,7 +174,7 @@ class IxiaResourceHelper(ClientResourceHelper): break self.client.ix_stop_traffic() - except Exception: + except Exception: # pylint: disable=broad-except LOG.exception("Run Traffic terminated") self._terminated.value = 1 @@ -201,9 +201,6 @@ class IxiaTrafficGen(SampleVNFTrafficGen): def _check_status(self): pass - def scale(self, flavor=""): - pass - def terminate(self): self.resource_helper.stop_collect() super(IxiaTrafficGen, self).terminate() diff --git a/yardstick/network_services/vnf_generic/vnf/tg_trex.py b/yardstick/network_services/vnf_generic/vnf/tg_trex.py index 4250cb7a6..0084a124c 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_trex.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_trex.py @@ -126,6 +126,11 @@ class TrexResourceHelper(ClientResourceHelper): self.ssh_helper.execute(self.MAKE_INSTALL.format(ko_src)) def start(self, ports=None, *args, **kwargs): + # pylint: disable=keyword-arg-before-vararg + # NOTE(ralonsoh): defining keyworded arguments before variable + # positional arguments is a bug. This function definition doesn't work + # in Python 2, although it works in Python 3. Reference: + # https://www.python.org/dev/peps/pep-3102/ cmd = "sudo fuser -n tcp {0.SYNC_PORT} {0.ASYNC_PORT} -k > /dev/null 2>&1" self.ssh_helper.execute(cmd.format(self)) @@ -186,9 +191,6 @@ class TrexTrafficGen(SampleVNFTrafficGen): super(TrexTrafficGen, self)._start_server() self.resource_helper.start() - def scale(self, flavor=""): - pass - def terminate(self): self.resource_helper.terminate() diff --git a/yardstick/ssh.py b/yardstick/ssh.py index e98ee98b7..6ddf327f2 100644 --- a/yardstick/ssh.py +++ b/yardstick/ssh.py @@ -379,6 +379,12 @@ class SSH(object): with SCPClient(client.get_transport()) as scp: scp.put(files, remote_path, recursive) + def get(self, remote_path, local_path='/tmp/', recursive=True): + client = self._get_client() + + with SCPClient(client.get_transport()) as scp: + scp.get(remote_path, local_path, recursive) + # keep shell running in the background, e.g. screen def send_command(self, command): client = self._get_client() |