Merge "Do not start collectd twice when SampleVNF is running on Baremetal"
authorRodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>
Mon, 14 May 2018 09:39:36 +0000 (09:39 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Mon, 14 May 2018 09:39:36 +0000 (09:39 +0000)
55 files changed:
INFO
INFO.yaml
ansible/multi_port_baremetal_ixia_correlated_test.yaml
ansible/multi_port_baremetal_ixia_test.yaml
ansible/nsb_setup.yml
ansible/roles/add_repos_jumphost/tasks/Debian.yml
ansible/standalone_ovs_scale_out_ixia_correlated_test.yaml
ansible/standalone_ovs_scale_out_ixia_test.yaml
ansible/standalone_sriov_scale_out_ixia_correlated_test.yaml
ansible/standalone_sriov_scale_out_ixia_test.yaml
docker/Dockerfile
docker/Dockerfile.aarch64.patch
docs/testing/developer/devguide/devguide.rst
docs/testing/user/userguide/13-nsb-installation.rst
docs/testing/user/userguide/code/pod_ixia.yaml [new file with mode: 0644]
etc/yardstick/nodes/apex_baremetal/pod.yaml [new file with mode: 0644]
etc/yardstick/nodes/apex_virtual/pod.yaml [new file with mode: 0644]
etc/yardstick/nodes/pod.yaml.nsb.sample.ixia
etc/yardstick/nodes/standalone/ixia_correlated_template.yaml
etc/yardstick/nodes/standalone/ixia_template.yaml
nsb_setup.sh
requirements.txt
samples/test_suite.yaml
samples/vnf_samples/nsut/prox/configs/gen_l2fwd-2.cfg
samples/vnf_samples/nsut/prox/configs/gen_l2fwd-4.cfg
samples/vnf_samples/vnf_descriptors/ixia_rfc2544_tpl.yaml
samples/vnf_samples/vnf_descriptors/tg_ixload.yaml
samples/vnf_samples/vnf_descriptors/tg_ixload_4port.yaml
tests/ci/prepare_env.sh
tests/opnfv/test_cases/opnfv_yardstick_tc092.yaml [new file with mode: 0644]
tests/opnfv/test_cases/opnfv_yardstick_tc093.yaml [new file with mode: 0644]
tests/opnfv/test_suites/opnfv_os-odl-nofeature-ha_daily.yaml
tests/opnfv/test_suites/opnfv_os-odl-nofeature-noha_daily.yaml
yardstick/benchmark/contexts/base.py
yardstick/benchmark/contexts/heat.py
yardstick/benchmark/scenarios/availability/attacker/attacker_process.py
yardstick/benchmark/scenarios/availability/attacker/baseattacker.py
yardstick/benchmark/scenarios/availability/director.py
yardstick/benchmark/scenarios/availability/ha_tools/start_service.bash
yardstick/benchmark/scenarios/availability/monitor/basemonitor.py
yardstick/benchmark/scenarios/availability/monitor/monitor_command.py
yardstick/benchmark/scenarios/availability/monitor/monitor_multi.py
yardstick/benchmark/scenarios/availability/monitor/monitor_process.py
yardstick/benchmark/scenarios/availability/serviceha.py
yardstick/common/constants.py
yardstick/common/openstack_utils.py
yardstick/network_services/libs/ixia_libs/IxNet/IxNet.py
yardstick/orchestrator/heat.py
yardstick/tests/integration/dummy-scenario-heat-context.yaml
yardstick/tests/unit/benchmark/contexts/test_base.py
yardstick/tests/unit/benchmark/contexts/test_heat.py
yardstick/tests/unit/common/test_openstack_utils.py
yardstick/tests/unit/common/test_packages.py [new file with mode: 0644]
yardstick/tests/unit/network_services/libs/ixia_libs/test_IxNet.py
yardstick/tests/unit/orchestrator/test_heat.py

diff --git a/INFO b/INFO
index 1a49af2..9bcc292 100644 (file)
--- a/INFO
+++ b/INFO
@@ -11,7 +11,6 @@ IRC: #opnfv-yardstick
 Repository: yardstick
 
 Committers:
-jorgen.w.karlsson@ericsson.com
 jean.gaoliang@huawei.com
 lvjing5@huawei.com
 wu.zhihui1@zte.com.cn
index 730cd4a..677c470 100644 (file)
--- a/INFO.yaml
+++ b/INFO.yaml
@@ -34,10 +34,6 @@ repositories:
     - 'yardstick'
 committers:
     - <<: *opnfv_yardstick_ptl
-    - name: 'Jörgen Karlsson'
-      email: 'jorgen.w.karlsson@ericsson.com'
-      company: 'ericsson.com'
-      id: 'jnon'
     - name: 'Kubi'
       email: 'jean.gaoliang@huawei.com'
       company: 'huawei.com'
index ba92b5c..0d22318 100644 (file)
@@ -42,7 +42,6 @@
         lib_path: "/opt/ixia/ixos-api/8.01.0.2/lib/ixTcl1.0"
         root_dir: "/opt/ixia/ixos-api/8.01.0.2/"
         py_bin_path: "/opt/ixia/ixload/8.01.106.3/bin/"
-        py_lib_path: "/opt/ixia/ixnetwork/8.01.1029.14/lib/PythonApi"
         dut_result_dir: "/mnt/results"
         version: "8.01.106.3"
       pcis:
index 52bc40b..d2dfaa3 100644 (file)
@@ -42,7 +42,6 @@
         lib_path: "/opt/ixia/ixos-api/8.01.0.2/lib/ixTcl1.0"
         root_dir: "/opt/ixia/ixos-api/8.01.0.2/"
         py_bin_path: "/opt/ixia/ixload/8.01.106.3/bin/"
-        py_lib_path: "/opt/ixia/ixnetwork/8.01.1029.14/lib/PythonApi"
         dut_result_dir: "/mnt/results"
         version: "8.01.106.3"
       pcis:
index 0149054..fcde1d1 100644 (file)
@@ -37,7 +37,7 @@
         name: yardstick
         pull: yes
         recreate: yes
-        image: opnfv/yardstick:latest
+        image: "{{ yardstick_docker_image|default('opnfv/yardstick:latest') }}"
         state: started
         restart_policy: always
         privileged: yes
index 0b67c66..626f0b0 100644 (file)
@@ -37,8 +37,7 @@
     replace: "# deb-src "
 
 - name: Add extra architecture
-  apt:
-    dpkg_options: "add-architecture {{ extra_arch }}"
+  command: "dpkg --add-architecture {{ extra_arch }}"
 
 - name: Define the default release version
   copy:
index 5166765..b54ea9b 100644 (file)
       user: ""
       password: ""
       key_filename: ~
-      tg_config: 
+      tg_config:
         ixchassis: "1.1.1.127" #ixia chassis ip
         tcl_port: "8009" # tcl server port
         lib_path: "/opt/ixia/ixos-api/8.01.0.2/lib/ixTcl1.0"
         root_dir: "/opt/ixia/ixos-api/8.01.0.2/"
         py_bin_path: "/opt/ixia/ixload/8.01.106.3/bin/"
-        py_lib_path: "/opt/ixia/ixnetwork/8.01.1029.14/lib/PythonApi"
         dut_result_dir: "/mnt/results"
         version: "8.01.106.3"
       pcis:
index ff66537..cae3734 100644 (file)
@@ -60,7 +60,6 @@
         lib_path: "/opt/ixia/ixos-api/8.01.0.2/lib/ixTcl1.0"
         root_dir: "/opt/ixia/ixos-api/8.01.0.2/"
         py_bin_path: "/opt/ixia/ixload/8.01.106.3/bin/"
-        py_lib_path: "/opt/ixia/ixnetwork/8.01.1029.14/lib/PythonApi"
         dut_result_dir: "/mnt/results"
         version: "8.01.106.3"
       pcis:
index 45a4a49..0e3a0af 100644 (file)
       user: ""
       password: ""
       key_filename: ~
-      tg_config: 
+      tg_config:
         ixchassis: "1.1.1.127" #ixia chassis ip
         tcl_port: "8009" # tcl server port
         lib_path: "/opt/ixia/ixos-api/8.01.0.2/lib/ixTcl1.0"
         root_dir: "/opt/ixia/ixos-api/8.01.0.2/"
         py_bin_path: "/opt/ixia/ixload/8.01.106.3/bin/"
-        py_lib_path: "/opt/ixia/ixnetwork/8.01.1029.14/lib/PythonApi"
         dut_result_dir: "/mnt/results"
         version: "8.01.106.3"
       pcis:
index 659dbef..8fb09d9 100644 (file)
@@ -49,7 +49,6 @@
         lib_path: "/opt/ixia/ixos-api/8.01.0.2/lib/ixTcl1.0"
         root_dir: "/opt/ixia/ixos-api/8.01.0.2/"
         py_bin_path: "/opt/ixia/ixload/8.01.106.3/bin/"
-        py_lib_path: "/opt/ixia/ixnetwork/8.01.1029.14/lib/PythonApi"
         dut_result_dir: "/mnt/results"
         version: "8.01.106.3"
       pcis:
index fed9f9b..62ea0d0 100644 (file)
@@ -31,13 +31,16 @@ RUN pip install appdirs==1.4.0 pyopenssl==17.5.0 python-openstackclient==3.11.0
 RUN mkdir -p ${REPOS_DIR}
 
 RUN git config --global http.sslVerify false
-##RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/yardstick ${YARDSTICK_REPO_DIR}
-RUN mkdir ${YARDSTICK_REPO_DIR}
-COPY ./ ${YARDSTICK_REPO_DIR}
+#For developers: To test your changes you must comment out the git clone for ${YARDSTICK_REPO_DIR}.
+#You must also uncomment the RUN and COPY commands below.
+#You must run docker build from your yardstick directory on the host.
+RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/yardstick ${YARDSTICK_REPO_DIR}
+#RUN mkdir ${YARDSTICK_REPO_DIR}
+#COPY ./ ${YARDSTICK_REPO_DIR}
 RUN git clone --depth 1 https://gerrit.opnfv.org/gerrit/releng ${RELENG_REPO_DIR}
 RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/storperf ${STORPERF_REPO_DIR}
 
-RUN ansible-playbook -vvv -e INSTALLATION_MODE="container" ${YARDSTICK_REPO_DIR}/ansible/install.yaml
+RUN ansible-playbook -c local -vvv -e INSTALLATION_MODE="container" ${YARDSTICK_REPO_DIR}/ansible/install.yaml
 
 RUN ${YARDSTICK_REPO_DIR}/docker/supervisor.sh
 
@@ -48,10 +51,10 @@ EXPOSE 5000 5672
 ADD http://download.cirros-cloud.net/0.3.5/cirros-0.3.5-x86_64-disk.img ${IMAGE_DIR}
 ADD http://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-amd64-disk1.img ${IMAGE_DIR}
 
-COPY ./docker/exec_tests.sh /usr/local/bin/
+COPY ./exec_tests.sh /usr/local/bin/
 
-ENV NSB_DIR="/opt/nsb_bin" \
-    PYTHONPATH="${PYTHONPATH}:${NSB_DIR}/trex_client:${NSB_DIR}/trex_client/stl"
+ENV NSB_DIR="/opt/nsb_bin"
+ENV PYTHONPATH="${PYTHONPATH}:${NSB_DIR}/trex_client:${NSB_DIR}/trex_client/stl"
 
 WORKDIR ${REPOS_DIR}
 CMD ["/usr/bin/supervisord"]
index 720a399..6c73812 100644 (file)
@@ -1,15 +1,14 @@
-From: Cristina Pauna <cristina.pauna@enea.com>
-Date: Mon, 30 Apr 2018 14:09:00 +0300
-Subject: [PATCH] [PATCH] Patch for Yardstick AARCH64 Docker file
+From: ting wu <ting.wu@enea.com>
+Date: Tue, 8 May 2018 14:02:52 +0200
+Subject: [PATCH][PATCH] Patch for Yardstick AARCH64 Docker file
 
-Signed-off-by: Cristina Pauna <cristina.pauna@enea.com>
-Signed-off-by: Alexandru Nemes <alexandru.nemes@enea.com>
+Signed-off-by: ting wu <ting.wu@enea.com>
 ---
- docker/Dockerfile | 12 +++++++-----
- 1 file changed, 7 insertions(+), 5 deletions(-)
+ docker/Dockerfile | 1++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
 
 diff --git a/docker/Dockerfile b/docker/Dockerfile
-index fed9f9bd..9654b5dc 100644
+index 62ea0d0..f2f41771 100644
 --- a/docker/Dockerfile
 +++ b/docker/Dockerfile
 @@ -7,9 +7,9 @@
@@ -24,18 +23,17 @@ index fed9f9bd..9654b5dc 100644
 
  ARG BRANCH=master
 
-@@ -24,7 +24,9 @@ ENV YARDSTICK_REPO_DIR="${REPOS_DIR}/yardstick/" \
+@@ -24,7 +24,8 @@ ENV YARDSTICK_REPO_DIR="${REPOS_DIR}/yardstick/" \
      RELENG_REPO_DIR="${REPOS_DIR}/releng" \
      STORPERF_REPO_DIR="${REPOS_DIR}/storperf"
 
 -RUN apt-get update && apt-get install -y git python python-setuptools python-pip && apt-get -y autoremove && apt-get clean
 +RUN apt-get update && apt-get install -y git python python-setuptools python-pip && apt-get -y autoremove && \
 +    apt-get install -y libssl-dev && apt-get -y install libffi-dev && apt-get clean
-+
  RUN easy_install -U setuptools==30.0.0
  RUN pip install appdirs==1.4.0 pyopenssl==17.5.0 python-openstackclient==3.11.0 python-heatclient==1.11.0 ansible==2.4.2
 
-@@ -45,8 +47,8 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf
+@@ -48,8 +49,8 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf
  # nginx=5000, rabbitmq=5672
  EXPOSE 5000 5672
 
@@ -44,5 +42,6 @@ index fed9f9bd..9654b5dc 100644
 +ADD http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-disk.img ${IMAGE_DIR}
 +ADD http://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-arm64-disk1.img ${IMAGE_DIR}
 
- COPY ./docker/exec_tests.sh /usr/local/bin/
+ COPY ./exec_tests.sh /usr/local/bin/
+
 
index dade49b..04d5350 100755 (executable)
@@ -432,7 +432,8 @@ Yardstick committers and contributors to review your codes.
    :width: 800px
    :alt: Gerrit for code review
 
-You can find Yardstick people info `here <https://wiki.opnfv.org/display/yardstick/People>`_.
+You can find a list Yardstick people `here <https://wiki.opnfv.org/display/yardstick/People>`_,
+or use the ``yardstick-reviewers`` and ``yardstick-committers`` groups in gerrit.
 
 Modify the code under review in Gerrit
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 1f6c79b..3e0ed0b 100644 (file)
@@ -1058,40 +1058,8 @@ IxLoad
 
   Config ``pod_ixia.yaml``
 
-  .. code-block:: yaml
-
-      nodes:
-          -
-            name: trafficgen_1
-            role: IxNet
-            ip: 1.2.1.1 #ixia machine ip
-            user: user
-            password: r00t
-            key_filename: /root/.ssh/id_rsa
-            tg_config:
-                ixchassis: "1.2.1.7" #ixia chassis ip
-                tcl_port: "8009" # tcl server port
-                lib_path: "/opt/ixia/ixos-api/8.01.0.2/lib/ixTcl1.0"
-                root_dir: "/opt/ixia/ixos-api/8.01.0.2/"
-                py_bin_path: "/opt/ixia/ixload/8.01.106.3/bin/"
-                py_lib_path: "/opt/ixia/ixnetwork/8.01.1029.14/lib/PythonApi"
-                dut_result_dir: "/mnt/ixia"
-                version: 8.1
-            interfaces:
-                xe0:  # logical name from topology.yaml and vnfd.yaml
-                    vpci: "2:5" # Card:port
-                    driver:    "none"
-                    dpdk_port_num: 0
-                    local_ip: "152.16.100.20"
-                    netmask:   "255.255.0.0"
-                    local_mac: "00:98:10:64:14:00"
-                xe1:  # logical name from topology.yaml and vnfd.yaml
-                    vpci: "2:6" # [(Card, port)]
-                    driver:    "none"
-                    dpdk_port_num: 1
-                    local_ip: "152.40.40.20"
-                    netmask:   "255.255.0.0"
-                    local_mac: "00:98:28:28:14:00"
+  .. literalinclude:: code/pod_ixia.yaml
+     :language: console
 
   for sriov/ovs_dpdk pod files, please refer to above Standalone Virtualization for ovs-dpdk/sriov configuration
 
@@ -1113,10 +1081,10 @@ IxLoad
 IxNetwork
 ---------
 
-1. Software needed: ``IxNetworkAPI<ixnetwork verson>Linux64.bin.tgz``
-   (Download from ixia support site)
-   Install - ``IxNetworkAPI<ixnetwork verson>Linux64.bin.tgz``
-2. Update pod_ixia.yaml file with ixia details.
+IxNetwork testcases use IxNetwork API Python Bindings module, which is
+installed as part of the requirements of the project.
+
+1. Update ``pod_ixia.yaml`` file with ixia details.
 
   .. code-block:: console
 
@@ -1124,44 +1092,12 @@ IxNetwork
 
   Config pod_ixia.yaml
 
-  .. code-block:: yaml
-
-      nodes:
-          -
-            name: trafficgen_1
-            role: IxNet
-            ip: 1.2.1.1 #ixia machine ip
-            user: user
-            password: r00t
-            key_filename: /root/.ssh/id_rsa
-            tg_config:
-                ixchassis: "1.2.1.7" #ixia chassis ip
-                tcl_port: "8009" # tcl server port
-                lib_path: "/opt/ixia/ixos-api/8.01.0.2/lib/ixTcl1.0"
-                root_dir: "/opt/ixia/ixos-api/8.01.0.2/"
-                py_bin_path: "/opt/ixia/ixload/8.01.106.3/bin/"
-                py_lib_path: "/opt/ixia/ixnetwork/8.01.1029.14/lib/PythonApi"
-                dut_result_dir: "/mnt/ixia"
-                version: 8.1
-            interfaces:
-                xe0:  # logical name from topology.yaml and vnfd.yaml
-                    vpci: "2:5" # Card:port
-                    driver:    "none"
-                    dpdk_port_num: 0
-                    local_ip: "152.16.100.20"
-                    netmask:   "255.255.0.0"
-                    local_mac: "00:98:10:64:14:00"
-                xe1:  # logical name from topology.yaml and vnfd.yaml
-                    vpci: "2:6" # [(Card, port)]
-                    driver:    "none"
-                    dpdk_port_num: 1
-                    local_ip: "152.40.40.20"
-                    netmask:   "255.255.0.0"
-                    local_mac: "00:98:28:28:14:00"
+  .. literalinclude:: code/pod_ixia.yaml
+     :language: console
 
   for sriov/ovs_dpdk pod files, please refer to above Standalone Virtualization for ovs-dpdk/sriov configuration
 
-3. Start IxNetwork TCL Server
+2. Start IxNetwork TCL Server
    You will also need to configure the IxNetwork machine to start the IXIA
    IxNetworkTclServer. This can be started like so:
 
@@ -1170,6 +1106,5 @@ IxNetwork
       ``Start->Programs->Ixia->IxNetwork->IxNetwork 7.21.893.14 GA->IxNetworkTclServer``
       (or ``IxNetworkApiServer``)
 
-4. Execute testcase in samplevnf folder e.g.
+3. Execute testcase in samplevnf folder e.g.
    ``<repo>/samples/vnf_samples/nsut/vfw/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_ixia.yaml``
-
diff --git a/docs/testing/user/userguide/code/pod_ixia.yaml b/docs/testing/user/userguide/code/pod_ixia.yaml
new file mode 100644 (file)
index 0000000..4ab56fe
--- /dev/null
@@ -0,0 +1,31 @@
+nodes:
+-
+    name: trafficgen_1
+    role: IxNet
+    ip: 1.2.1.1 #ixia machine ip
+    user: user
+    password: r00t
+    key_filename: /root/.ssh/id_rsa
+    tg_config:
+        ixchassis: "1.2.1.7" #ixia chassis ip
+        tcl_port: "8009" # tcl server port
+        lib_path: "/opt/ixia/ixos-api/8.01.0.2/lib/ixTcl1.0"
+        root_dir: "/opt/ixia/ixos-api/8.01.0.2/"
+        py_bin_path: "/opt/ixia/ixload/8.01.106.3/bin/"
+        dut_result_dir: "/mnt/ixia"
+        version: 8.1
+    interfaces:
+        xe0:  # logical name from topology.yaml and vnfd.yaml
+            vpci: "2:5" # Card:port
+            driver:    "none"
+            dpdk_port_num: 0
+            local_ip: "152.16.100.20"
+            netmask:   "255.255.0.0"
+            local_mac: "00:98:10:64:14:00"
+        xe1:  # logical name from topology.yaml and vnfd.yaml
+            vpci: "2:6" # [(Card, port)]
+            driver:    "none"
+            dpdk_port_num: 1
+            local_ip: "152.40.40.20"
+            netmask:   "255.255.0.0"
+            local_mac: "00:98:28:28:14:00"
diff --git a/etc/yardstick/nodes/apex_baremetal/pod.yaml b/etc/yardstick/nodes/apex_baremetal/pod.yaml
new file mode 100644 (file)
index 0000000..4b058c4
--- /dev/null
@@ -0,0 +1,46 @@
+##############################################################################
+# Copyright (c) 2018 Intracom Telecom 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
+##############################################################################
+---
+nodes:
+-
+    name: node1
+    role: Controller
+    ip: ip1
+    user: heat-admin
+    key_filename: node_keyfile
+-
+    name: node2
+    role: Controller
+    ip: ip2
+    user: heat-admin
+    key_filename: node_keyfile
+-
+    name: node3
+    role: Controller
+    ip: ip3
+    user: heat-admin
+    key_filename: node_keyfile
+-
+    name: node4
+    role: Compute
+    ip: ip4
+    user: heat-admin
+    key_filename: node_keyfile
+-
+    name: node5
+    role: Compute
+    ip: ip5
+    user: heat-admin
+    key_filename: node_keyfile
+-
+    name: node6
+    role: Opendaylight-Cluster-Leader
+    ip: ip6
+    user: heat-admin
+    key_filename: node_keyfile
diff --git a/etc/yardstick/nodes/apex_virtual/pod.yaml b/etc/yardstick/nodes/apex_virtual/pod.yaml
new file mode 100644 (file)
index 0000000..59b51d2
--- /dev/null
@@ -0,0 +1,40 @@
+##############################################################################
+# Copyright (c) 2018 Intracom Telecom 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
+##############################################################################
+---
+nodes:
+-
+    name: node1
+    role: Controller
+    ip: 192.0.2.15
+    user: heat-admin
+    key_filename: /root/.ssh/id_rsa
+-
+    name: node2
+    role: Controller
+    ip: 192.0.2.4
+    user: heat-admin
+    key_filename: /root/.ssh/id_rsa
+-
+    name: node3
+    role: Controller
+    ip: 192.0.2.6
+    user: heat-admin
+    key_filename: /root/.ssh/id_rsa
+-
+    name: node4
+    role: Compute
+    ip: 192.0.2.10
+    user: heat-admin
+    key_filename: /root/.ssh/id_rsa
+-
+    name: node5
+    role: Compute
+    ip: 192.0.2.14
+    user: heat-admin
+    key_filename: /root/.ssh/id_rsa
index 57a8305..1f755dc 100644 (file)
@@ -26,7 +26,6 @@ nodes:
         lib_path: "/opt/ixia/ixos-api/8.01.0.2/lib/ixTcl1.0"
         root_dir: "/opt/ixia/ixos-api/8.01.0.2/"
         py_bin_path: "/opt/ixia/ixload/8.01.106.3/bin/"
-        py_lib_path: "/opt/ixia/ixnetwork/8.01.1029.14/lib/PythonApi"
         dut_result_dir: "/mnt/ixia"
         version: 8.1
     interfaces:
index 7250c4c..ef63ea0 100644 (file)
@@ -26,13 +26,12 @@ nodes:
     user: {{gen.user}}
     password: {{gen.password}}
     key_filename: {{gen.key_filename}}
-    tg_config: 
+    tg_config:
         ixchassis: "{{gen.tg_config.ixchassis}}" #ixia chassis ip
         tcl_port: "{{gen.tg_config.tcl_port}}" # tcl server port
         lib_path: "{{gen.tg_config.lib_path}}"
         root_dir: "{{gen.tg_config.root_dir}}"
         py_bin_path: "{{gen.tg_config.py_bin_path}}"
-        py_lib_path: "{{gen.tg_config.py_lib_path}}"
         dut_result_dir: "{{gen.tg_config.dut_result_dir}}"
         version: "{{gen.tg_config.version}}"
     interfaces:
index 617a651..98ed8c5 100644 (file)
@@ -32,7 +32,6 @@ nodes:
       lib_path: "{{gen.tg_config.lib_path}}"
       root_dir: "{{gen.tg_config.root_dir}}"
       py_bin_path: "{{gen.tg_config.py_bin_path}}"
-      py_lib_path: "{{gen.tg_config.py_lib_path}}"
       dut_result_dir: "{{gen.tg_config.dut_result_dir}}"
       version: "{{gen.tg_config.version}}"
     interfaces:
index 50fc017..86796c4 100755 (executable)
@@ -67,8 +67,16 @@ pip install ansible==2.4.2 shade==1.22.2 docker-py==1.10.6
 
 ANSIBLE_SCRIPTS="ansible"
 
+if [[ -n ${1} ]]; then
+    yardstick_docker_image="-e yardstick_docker_image=${1}"
+else
+    yardstick_docker_image=""
+fi
+
+# no quotes for yardstick_docker_image so when empty it is removed as whitespace
 cd ${ANSIBLE_SCRIPTS} &&\
 ansible-playbook \
          -e img_property="nsb" \
+         ${yardstick_docker_image} \
          -e YARD_IMG_ARCH='amd64' ${extra_args}\
          -i yardstick-install-inventory.ini nsb_setup.yml
index 43f0e79..4679bc8 100644 (file)
@@ -26,6 +26,7 @@ flask==0.11.1           # BSD; OSI Approved  BSD License
 functools32==3.2.3.post2; python_version <= "2.7"    # PSF license
 futures==3.1.1;python_version=='2.7'    # BSD; OSI Approved  BSD License
 influxdb==4.1.1         # MIT License; OSI Approved  MIT License
+IxNetwork==8.40.1124.9  # MIT License; OSI Approved  MIT License
 jinja2schema==0.1.4     # OSI Approved  BSD License
 keystoneauth1==3.1.0    # OSI Approved  Apache Software License
 kubernetes==3.0.0a1     # OSI Approved  Apache Software License
index 9a766b0..6f5f53b 100644 (file)
@@ -20,7 +20,8 @@ test_cases:
   file_name: ping.yaml
 -
   file_name: ping-template.yaml
-  task_args: '{"packetsize": "200"}'
+  task_args:
+    default: '{"packetsize": "200"}'
 -
   file_name: ping-template.yaml
   task_args_file: "/tmp/test-args-file.json"
index 192f2f8..ba00553 100644 (file)
@@ -49,7 +49,7 @@ mode=gen
 tx port=p0
 bps=1250000000
 ; Ethernet + IP + UDP
-pkt inline=${sut_mac0} 3c fd fe 9f a3 08 08 00 45 45 00 00 1c 00 01 00 00 40 11 f7 7d c0 a8 01 01 c0 a8 01 01 13 88 13 88 00 08 55 7b
+pkt inline=${sut_mac0} 3c fd fe 9f a3 08 08 00 45 00 00 1c 00 01 00 00 40 11 f7 7d c0 a8 01 01 c0 a8 01 01 13 88 13 88 00 08 55 7b
 lat pos=38
 
 [core 2]
@@ -59,7 +59,7 @@ mode=gen
 tx port=p1
 bps=1250000000
 ; Ethernet + IP + UDP
-pkt inline=${sut_mac1} 3c fd fe 9f a3 08 08 00 45 45 00 00 1c 00 01 00 00 40 11 f7 7d c0 a8 01 01 c0 a8 01 01 13 88 13 88 00 08 55 7b
+pkt inline=${sut_mac1} 3c fd fe 9f a3 08 08 00 45 00 00 1c 00 01 00 00 40 11 f7 7d c0 a8 01 01 c0 a8 01 01 13 88 13 88 00 08 55 7b
 lat pos=38
 
 [core 3]
@@ -67,12 +67,10 @@ name=rec 0
 task=0
 mode=lat
 rx port=p0
-lat pos=38
 
 [core 4]
 name=rec 0
 task=0
 mode=lat
 rx port=p1
-lat pos=38
 
index 0db21b6..41c31bf 100644 (file)
@@ -61,7 +61,7 @@ mode=gen
 tx port=p0
 bps=1250000000
 ; Ethernet + IP + UDP
-pkt inline=${sut_mac0} 3c fd fe 9f a3 08 08 00 45 45 00 00 1c 00 01 00 00 40 11 f7 7d c0 a8 01 01 c0 a8 01 01 13 88 13 88 00 08 55 7b
+pkt inline=${sut_mac0} 3c fd fe 9f a3 08 08 00 45 00 00 1c 00 01 00 00 40 11 f7 7d c0 a8 01 01 c0 a8 01 01 13 88 13 88 00 08 55 7b
 lat pos=38
 
 [core 2]
@@ -71,7 +71,7 @@ mode=gen
 tx port=p1
 bps=1250000000
 ; Ethernet + IP + UDP
-pkt inline=${sut_mac1} 3c fd fe 9f a3 08 08 00 45 45 00 00 1c 00 01 00 00 40 11 f7 7d c0 a8 01 01 c0 a8 01 01 13 88 13 88 00 08 55 7b
+pkt inline=${sut_mac1} 3c fd fe 9f a3 08 08 00 45 00 00 1c 00 01 00 00 40 11 f7 7d c0 a8 01 01 c0 a8 01 01 13 88 13 88 00 08 55 7b
 lat pos=38
 
 [core 3]
@@ -81,7 +81,7 @@ mode=gen
 tx port=p2
 bps=1250000000
 ; Ethernet + IP + UDP
-pkt inline=${sut_mac2} 3c fd fe 9f a5 08 08 00 45 45 00 00 1c 00 01 00 00 40 11 f7 7d c0 a8 01 01 c0 a8 01 01 13 88 13 88 00 08 55 7b
+pkt inline=${sut_mac2} 3c fd fe 9f a5 08 08 00 45 00 00 1c 00 01 00 00 40 11 f7 7d c0 a8 01 01 c0 a8 01 01 13 88 13 88 00 08 55 7b
 lat pos=38
 
 [core 4]
@@ -91,7 +91,7 @@ mode=gen
 tx port=p3
 bps=1250000000
 ; Ethernet + IP + UDP
-pkt inline=${sut_mac3} 3c fd fe 9f a5 08 08 00 45 45 00 00 1c 00 01 00 00 40 11 f7 7d c0 a8 01 01 c0 a8 01 01 13 88 13 88 00 08 55 7b
+pkt inline=${sut_mac3} 3c fd fe 9f a5 08 08 00 45 00 00 1c 00 01 00 00 40 11 f7 7d c0 a8 01 01 c0 a8 01 01 13 88 13 88 00 08 55 7b
 lat pos=38
 
 [core 5]
@@ -99,25 +99,22 @@ name=rec 0
 task=0
 mode=lat
 rx port=p0
-lat pos=38
 
 [core 6]
 name=rec 1
 task=0
 mode=lat
 rx port=p1
-lat pos=38
 
 [core 7]
 name=rec 2
 task=0
 mode=lat
 rx port=p2
-lat pos=38
 
 [core 8]
 name=rec 3
 task=0
 mode=lat
 rx port=p3
-lat pos=38
\ No newline at end of file
+
index 9b2a152..aca7c21 100644 (file)
@@ -29,7 +29,6 @@ vnfd:vnfd-catalog:
                 tcl_port: '{{tg_config.tcl_port}}' # tcl server port
                 lib_path: '{{tg_config.lib_path}}'
                 root_dir: '{{tg_config.root_dir}}'
-                py_lib_path: '{{tg_config.py_lib_path}}'
                 py_bin_path: '{{tg_config.py_bin_path}}'
                 dut_result_dir: '{{tg_config.dut_result_dir}}'
                 version: '{{tg_config.version}}'
index ad4953f..0324bb8 100644 (file)
@@ -29,7 +29,6 @@ vnfd:vnfd-catalog:
                 tcl_port: '{{tg_config.tcl_port}}' # tcl server port
                 lib_path: '{{tg_config.lib_path}}'
                 root_dir: '{{tg_config.root_dir}}'
-                py_lib_path: '{{tg_config.py_lib_path}}'
                 py_bin_path: '{{tg_config.py_bin_path}}'
                 dut_result_dir: '{{tg_config.dut_result_dir}}'
                 version: '{{tg_config.version}}'
index ffbfbde..def8cdc 100644 (file)
@@ -28,7 +28,6 @@ vnfd:vnfd-catalog:
                 tcl_port: '{{tg_config.tcl_port}}' # tcl server port
                 lib_path: '{{tg_config.lib_path}}'
                 root_dir: '{{tg_config.root_dir}}'
-                py_lib_path: '{{tg_config.py_lib_path}}'
                 dut_result_dir: '{{tg_config.dut_result_dir}}'
                 version: '{{tg_config.version}}'
         vdu:
index d7c60d4..8b9f887 100755 (executable)
@@ -16,6 +16,7 @@
 : ${EXTERNAL_NETWORK:='admin_floating_net'}
 : ${USER_NAME:='ubuntu'}
 : ${SSH_KEY:='/root/.ssh/id_rsa'}
+: ${DEPLOY_SCENARIO:='unknown'}
 
 # Extract network name from EXTERNAL_NETWORK
 #  e.g. EXTERNAL_NETWORK='ext-net;flat;192.168.0.2;192.168.0.253;192.168.0.1;192.168.0.0/24'
@@ -62,7 +63,73 @@ verify_connectivity() {
 }
 
 ssh_options="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
+if [ "$INSTALLER_TYPE" == "apex" ]; then
 
+    # check the connection
+    verify_connectivity "${INSTALLER_IP}"
+
+    pod_yaml="$YARDSTICK_REPO_DIR/etc/yardstick/nodes/apex_baremetal/pod.yaml"
+
+    # update "ip" according to the CI env
+    ssh -l root "${INSTALLER_IP}" -i ${SSH_KEY} ${ssh_options} \
+         "source /home/stack/stackrc && openstack server list -f yaml" > node_info
+
+    controller_ips=($(awk '/control/{getline; {print $2}}' < node_info | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'))
+    compute_ips=($(awk '/compute/{getline; {print $2}}' < node_info | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'))
+    odl_ip=""
+    # Get ODL's cluster default module-shard Leader IP in HA scenario
+    if [[ ${DEPLOY_SCENARIO} == os-odl-*-ha ]]; then
+        for ip in "${controller_ips[@]}";
+        do
+           if [[ "$odl_ip" ]]; then
+               break
+           fi
+           for ((i=0; i<${#controller_ips[@]}; i++));
+           do
+               ODL_STATE=$(curl -s -u admin:admin -H "Accept: application/json" -H "Content-Type: application/json" \
+                           "http://"${ip}":8081/jolokia/read/org.opendaylight.controller:Category=Shards,name=member-"${i}"-shard-default-operational,type=DistributedOperationalDatastore" \
+                           | grep -o \"RaftState\"\:\"Leader\" | tr ":" "\n" | sed -n '2p' | sed 's/\"//g');
+
+               if [[ ${ODL_STATE} == "Leader" ]]; then
+                    odl_ip=${ip}
+                    break
+               fi
+           done;
+        done
+
+        if [[ -z "$odl_ip" ]]; then
+          echo "ERROR: Opendaylight Leader IP is emtpy"
+          exit 1
+        fi
+
+    elif [[ ${DEPLOY_SCENARIO} == *"odl"* ]]; then
+        odl_ip=${controller_ips[0]}
+    fi
+
+    if [[ ${controller_ips[0]} ]]; then
+        sed -i "s|ip1|${controller_ips[0]}|" "${pod_yaml}"
+    fi
+    if [[ ${controller_ips[1]} ]]; then
+        sed -i "s|ip2|${controller_ips[1]}|" "${pod_yaml}"
+    fi
+    if [[ ${controller_ips[2]} ]]; then
+        sed -i "s|ip3|${controller_ips[2]}|" "${pod_yaml}"
+    fi
+    if [[ ${compute_ips[0]} ]]; then
+        sed -i "s|ip4|${compute_ips[0]}|" "${pod_yaml}"
+    fi
+    if [[ ${compute_ips[1]} ]]; then
+        sed -i "s|ip5|${compute_ips[1]}|" "${pod_yaml}"
+    fi
+    if [[ ${odl_ip} ]]; then
+        sed -i "s|ip6|${odl_ip}|" "${pod_yaml}"
+    fi
+
+
+    # update 'key_filename' according to the CI env
+    sed -i "s|node_keyfile|${SSH_KEY}|" "${pod_yaml}"
+
+fi
 if [ "$INSTALLER_TYPE" == "fuel" ]; then
 
     # check the connection
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc092.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc092.yaml
new file mode 100644 (file)
index 0000000..85ec510
--- /dev/null
@@ -0,0 +1,276 @@
+##############################################################################
+## Copyright (c) 2018 Intracom Telecom 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 TC092 config file;
+    SDN Controller resilience in HA configuration
+
+{% set file = file or '/etc/yardstick/pod.yaml' %}
+{% set attack_host = attack_host or 'node6' %}
+
+scenarios:
+
+-
+      type: "GeneralHA"
+      options:
+          monitors:
+            - monitor_type: "general-monitor"
+              monitor_key: "ip-status"
+              key: "snat"
+              monitor_time: 50
+              host: athena
+              sla:
+                 max_outage_time: 0
+              parameter:
+                destination_ip: "8.8.8.8"
+
+            - monitor_type: "general-monitor"
+              monitor_key: "ip-status"
+              key: "l2"
+              monitor_time: 50
+              host: athena
+              sla:
+                 max_outage_time: 0
+              parameter:
+                destination_ip: "@private_ip"
+
+          operations:
+            - operation_type: "general-operation"
+              key: "get-privateip"
+              operation_key: "get-privateip"
+              action_parameter:
+                server_name: "ares"
+              return_parameter:
+                all: "@private_ip"
+
+
+          steps:
+            - actionKey: "get-privateip"
+              actionType: "operation"
+              index: 1
+
+            - actionKey: "l2"
+              actionType: "monitor"
+              index: 2
+
+            - actionKey: "snat"
+              actionType: "monitor"
+              index: 3
+
+
+      nodes:
+        {{attack_host}}: {{attack_host}}.LF
+        athena: athena.ODLHA1
+      runner:
+        type: Duration
+        duration: 1
+      sla:
+        action: monitor
+
+-
+      type: "GeneralHA"
+      options:
+          attackers:
+            -
+              fault_type: "kill-process"
+              process_name: "opendaylight"
+              key: "kill-process"
+              host: {{attack_host}}
+
+          monitors:
+            - monitor_type: "process"
+              process_name: "opendaylight"
+              host: {{attack_host}}
+              key: "monitor-recovery"
+              monitor_time: 50
+              sla:
+                max_recover_time: 30
+
+
+            - monitor_type: "general-monitor"
+              monitor_key: "ip-status"
+              key: "snat"
+              monitor_time: 70
+              host: athena
+              sla:
+                 max_outage_time: 0
+              parameter:
+                destination_ip: "8.8.8.8"
+
+            - monitor_type: "general-monitor"
+              monitor_key: "ip-status"
+              key: "l2"
+              monitor_time: 70
+              host: athena
+              sla:
+                 max_outage_time: 0
+              parameter:
+                destination_ip: "@private_ip"
+
+          operations:
+            - operation_type: "general-operation"
+              key: "start-service"
+              host: {{attack_host}}
+              operation_key: "start-service"
+              action_parameter:
+                service: "opendaylight"
+              rollback_parameter:
+                service: "opendaylight"
+
+            - operation_type: "general-operation"
+              key: "get-privateip"
+              operation_key: "get-privateip"
+              action_parameter:
+                server_name: "ares"
+              return_parameter:
+                all: "@private_ip"
+
+
+
+          steps:
+
+            - actionKey: "monitor-recovery"
+              actionType: "monitor"
+              index: 1
+
+            - actionKey: "get-privateip"
+              actionType: "operation"
+              index: 2
+
+            - actionKey: "l2"
+              actionType: "monitor"
+              index: 3
+
+            - actionKey: "snat"
+              actionType: "monitor"
+              index: 4
+
+            - actionKey: "kill-process"
+              actionType: "attacker"
+              index: 5
+
+            - actionKey: "start-service"
+              actionType: "operation"
+              index: 6
+
+
+
+      nodes:
+        {{attack_host}}: {{attack_host}}.LF
+        athena: athena.ODLHA1
+      runner:
+        type: Duration
+        duration: 1
+      sla:
+        action: monitor
+
+-
+      type: "GeneralHA"
+      options:
+          monitors:
+
+            - monitor_type: "general-monitor"
+              monitor_key: "ip-status"
+              key: "l2"
+              monitor_time: 80
+              host: athena
+              sla:
+                 max_outage_time: 40
+              parameter:
+                destination_ip: "@private_ip"
+
+          operations:
+            - operation_type: "general-operation"
+              key: "get-privateip"
+              operation_key: "get-privateip"
+              action_parameter:
+                server_name: "hermes"
+              return_parameter:
+                all: "@private_ip"
+
+            - operation_type: "general-operation"
+              key: "nova-create-instance"
+              operation_key: "nova-create-instance"
+              action_parameter:
+                serverconfig: "hermes yardstick-image yardstick-flavor test_one"
+              rollback_parameter:
+                serverconfig: "hermes"
+
+            - operation_type: "general-operation"
+              key: "add-server-to-secgroup"
+              operation_key: "add-server-to-secgroup"
+              action_parameter:
+                serverconfig: "hermes ODLHA1"
+              rollback_parameter:
+                serverconfig: "hermes ODLHA1"
+
+
+          steps:
+            - actionKey: "nova-create-instance"
+              actionType: "operation"
+              index: 1
+
+            - actionKey: "add-server-to-secgroup"
+              actionType: "operation"
+              index: 2
+
+            - actionKey: "get-privateip"
+              actionType: "operation"
+              index: 3
+
+            - actionKey: "l2"
+              actionType: "monitor"
+              index: 4
+
+      nodes:
+        {{attack_host}}: {{attack_host}}.LF
+        athena: athena.ODLHA1
+      runner:
+        type: Duration
+        duration: 1
+      sla:
+        action: monitor
+
+
+contexts:
+    -
+        type: Node
+        name: LF
+        file: {{file}}
+    -
+        name: ODLHA1
+        image: yardstick-image
+        flavor: yardstick-flavor
+        user: ubuntu
+        host: athena
+        placement_groups:
+            pgrp1:
+                policy: "availability"
+        servers:
+            athena:
+                floating_ip: true
+                placement: "pgrp1"
+                network_ports:
+                    test_one:
+                        - ens0
+
+            ares:
+                floating_ip: true
+                placement: "pgrp1"
+                network_ports:
+                    test_one:
+                        - ens0
+
+        networks:
+            test_one:
+                cidr: '10.0.1.0/24'
+                router: 'test_router'
+
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc093.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc093.yaml
new file mode 100644 (file)
index 0000000..a034471
--- /dev/null
@@ -0,0 +1,313 @@
+##############################################################################
+## Copyright (c) 2018 Intracom Telecom 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 TC093 config file;
+    SDN Vswitch resilience in non-HA or HA configuration
+
+{% set file = file or '/etc/yardstick/pod.yaml' %}
+{% set attack_host_cmp_one = attack_host_cmp_one or 'node4' %}
+{% set attack_host_cmp_two = attack_host_cmp_two or 'node5' %}
+{% set systemd_service_name = systemd_service_name or 'openvswitch-switch'%}
+
+scenarios:
+
+-
+      type: "GeneralHA"
+      options:
+          monitors:
+
+            - monitor_type: "general-monitor"
+              monitor_key: "ip-status"
+              key: "snat"
+              monitor_time: 50
+              host: athena
+              sla:
+                 max_outage_time: 0
+              parameter:
+                destination_ip: "8.8.8.8"
+
+            - monitor_type: "general-monitor"
+              monitor_key: "ip-status"
+              key: "l2"
+              monitor_time: 50
+              host: athena
+              sla:
+                 max_outage_time: 0
+              parameter:
+                destination_ip: "@private_ip"
+
+          operations:
+            - operation_type: "general-operation"
+              key: "get-privateip"
+              operation_key: "get-privateip"
+              action_parameter:
+                server_name: "ares"
+              return_parameter:
+                all: "@private_ip"
+
+
+          steps:
+            - actionKey: "get-privateip"
+              actionType: "operation"
+              index: 1
+
+            - actionKey: "l2"
+              actionType: "monitor"
+              index: 2
+
+            - actionKey: "snat"
+              actionType: "monitor"
+              index: 3
+
+
+      nodes:
+        athena: athena.ODLnoHA1
+      runner:
+        type: Duration
+        duration: 1
+      sla:
+        action: monitor
+
+
+-
+      type: "GeneralHA"
+      options:
+          attackers:
+            -
+              fault_type: "kill-process"
+              process_name: "openvswitch"
+              key: "kill-process-cmp-one"
+              host: {{attack_host_cmp_one}}
+
+            -
+              fault_type: "kill-process"
+              process_name: "openvswitch"
+              key: "kill-process-cmp-two"
+              host: {{attack_host_cmp_two}}
+
+          monitors:
+            - monitor_type: "process"
+              process_name: "openvswitch"
+              host: {{attack_host_cmp_one}}
+              key: "monitor-recovery-cmp-one"
+              monitor_time: 50
+              sla:
+                max_recover_time: 30
+
+            - monitor_type: "process"
+              process_name: "openvswitch"
+              host: {{attack_host_cmp_two}}
+              key: "monitor-recovery-cmp-two"
+              monitor_time: 50
+              sla:
+                max_recover_time: 30
+
+            - monitor_type: "general-monitor"
+              monitor_key: "ip-status"
+              key: "snat"
+              monitor_time: 70
+              host: athena
+              sla:
+                 max_outage_time: 20
+              parameter:
+                destination_ip: "8.8.8.8"
+
+            - monitor_type: "general-monitor"
+              monitor_key: "ip-status"
+              key: "l2"
+              monitor_time: 70
+              host: athena
+              sla:
+                 max_outage_time: 20
+              parameter:
+                destination_ip: "@private_ip"
+
+          operations:
+            - operation_type: "general-operation"
+              key: "restart-service-cmp-one"
+              host: {{attack_host_cmp_one}}
+              operation_key: "start-service"
+              action_parameter:
+                service: {{systemd_service_name ~ " restart"}}
+              rollback_parameter:
+                service: "openvswitch"
+
+            - operation_type: "general-operation"
+              key: "restart-service-cmp-two"
+              host: {{attack_host_cmp_two}}
+              operation_key: "start-service"
+              action_parameter:
+                service: {{systemd_service_name ~ " restart"}}
+              rollback_parameter:
+                service: "openvswitch"
+
+            - operation_type: "general-operation"
+              key: "get-privateip"
+              operation_key: "get-privateip"
+              action_parameter:
+                server_name: "ares"
+              return_parameter:
+                all: "@private_ip"
+
+
+
+          steps:
+
+            - actionKey: "get-privateip"
+              actionType: "operation"
+              index: 1
+
+            - actionKey: "l2"
+              actionType: "monitor"
+              index: 2
+
+            - actionKey: "snat"
+              actionType: "monitor"
+              index: 3
+
+            - actionKey: "kill-process-cmp-one"
+              actionType: "attacker"
+              index: 4
+
+            - actionKey: "kill-process-cmp-two"
+              actionType: "attacker"
+              index: 5
+
+            - actionKey: "monitor-recovery-cmp-one"
+              actionType: "monitor"
+              index: 6
+
+            - actionKey: "monitor-recovery-cmp-two"
+              actionType: "monitor"
+              index: 7
+
+
+            - actionKey: "restart-service-cmp-one"
+              actionType: "operation"
+              index: 8
+
+            - actionKey: "restart-service-cmp-two"
+              actionType: "operation"
+              index: 9
+
+
+      nodes:
+        {{attack_host_cmp_one}}: {{attack_host_cmp_one}}.LF
+        {{attack_host_cmp_two}}: {{attack_host_cmp_two}}.LF
+        athena: athena.ODLnoHA1
+      runner:
+        type: Duration
+        duration: 1
+      sla:
+        action: monitor
+
+-
+      type: "GeneralHA"
+      options:
+          monitors:
+
+            - monitor_type: "general-monitor"
+              monitor_key: "ip-status"
+              key: "l2"
+              monitor_time: 80
+              host: athena
+              sla:
+                 max_outage_time: 40
+              parameter:
+                destination_ip: "@private_ip"
+
+          operations:
+            - operation_type: "general-operation"
+              key: "get-privateip"
+              operation_key: "get-privateip"
+              action_parameter:
+                server_name: "hermes"
+              return_parameter:
+                all: "@private_ip"
+
+            - operation_type: "general-operation"
+              key: "nova-create-instance"
+              operation_key: "nova-create-instance"
+              action_parameter:
+                serverconfig: "hermes yardstick-image yardstick-flavor test_one"
+              rollback_parameter:
+                serverconfig: "hermes"
+
+            - operation_type: "general-operation"
+              key: "add-server-to-secgroup"
+              operation_key: "add-server-to-secgroup"
+              action_parameter:
+                serverconfig: "hermes ODLnoHA1"
+              rollback_parameter:
+                serverconfig: "hermes ODLnoHA1"
+
+
+          steps:
+            - actionKey: "nova-create-instance"
+              actionType: "operation"
+              index: 1
+
+            - actionKey: "add-server-to-secgroup"
+              actionType: "operation"
+              index: 2
+
+            - actionKey: "get-privateip"
+              actionType: "operation"
+              index: 3
+
+            - actionKey: "l2"
+              actionType: "monitor"
+              index: 4
+
+      nodes:
+        athena: athena.ODLnoHA1
+      runner:
+        type: Duration
+        duration: 1
+      sla:
+        action: monitor
+
+
+contexts:
+    -
+        type: Node
+        name: LF
+        file: {{file}}
+    -
+        name: ODLnoHA1
+        image: yardstick-image
+        flavor: yardstick-flavor
+        user: ubuntu
+        host: athena
+        placement_groups:
+            pgrp1:
+                policy: "availability"
+        servers:
+            athena:
+                floating_ip: true
+                placement: "pgrp1"
+                network_ports:
+                    test_one:
+                        - ens0
+
+            ares:
+                floating_ip: true
+                placement: "pgrp1"
+                network_ports:
+                    test_one:
+                        - ens0
+
+        networks:
+            test_one:
+                cidr: '10.0.1.0/24'
+                router: 'test_router'
+
index 13cc710..f174a90 100644 (file)
@@ -62,3 +62,18 @@ test_cases:
   task_args:
       huawei-pod1: '{"file": "etc/yardstick/nodes/compass_sclab_physical/pod.yaml",
       "host": "node1"}'
+-
+  file_name: opnfv_yardstick_tc092.yaml
+  constraint:
+      installer: apex
+  task_args:
+      default: '{"file": "etc/yardstick/nodes/apex_baremetal/pod.yaml",
+      "attack_host": "node6"}'
+-
+  file_name: opnfv_yardstick_tc093.yaml
+  constraint:
+      installer: apex
+  task_args:
+      default: '{"file": "etc/yardstick/nodes/apex_baremetal/pod.yaml",
+      "attack_host_cmp_one": "node4","attack_host_cmp_two": "node5",
+      "systemd_service_name": "openvswitch"}'
index 42a170a..feb8a66 100644 (file)
@@ -61,3 +61,11 @@ test_cases:
   task_args:
       default: '{"file": "etc/yardstick/nodes/fuel_baremetal/pod.yaml",
       "attack_host": "node6"}'
+-
+  file_name: opnfv_yardstick_tc093.yaml
+  constraint:
+      installer: apex
+  task_args:
+      default: '{"file": "etc/yardstick/nodes/apex_baremetal/pod.yaml",
+      "attack_host_cmp_one": "node4","attack_host_cmp_two": "node5",
+      "systemd_service_name": "openvswitch"}'
index ae8319e..692c168 100644 (file)
@@ -6,17 +6,20 @@
 # which accompanies this distribution, and is available at
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
+
 import abc
 import six
 
-import yardstick.common.utils as utils
+from yardstick.common import constants
+from yardstick.common import utils
 
 
 class Flags(object):
     """Class to represent the status of the flags in a context"""
 
     _FLAGS = {'no_setup': False,
-              'no_teardown': False}
+              'no_teardown': False,
+              'os_cloud_config': constants.OS_CLOUD_DEFAULT_CONFIG}
 
     def __init__(self, **kwargs):
         for name, value in self._FLAGS.items():
index 0964b7b..8286182 100644 (file)
@@ -325,8 +325,10 @@ class HeatContext(Context):
         if not os.path.exists(self.key_filename):
             SSH.gen_keys(self.key_filename)
 
-        heat_template = HeatTemplate(self.name, self.template_file,
-                                     self.heat_parameters)
+        heat_template = HeatTemplate(
+            self.name, template_file=self.template_file,
+            heat_parameters=self.heat_parameters,
+            os_cloud_config=self._flags.os_cloud_config)
 
         if self.template_file is None:
             self._add_resources_to_template(heat_template)
index cb171ea..7f1136c 100644 (file)
@@ -42,29 +42,28 @@ class ProcessAttacker(BaseAttacker):
 
     def check(self):
         with open(self.check_script, "r") as stdin_file:
-            exit_status, stdout, stderr = self.connection.execute(
+            _, stdout, stderr = self.connection.execute(
                 "sudo /bin/sh -s {0}".format(self.service_name),
                 stdin=stdin_file)
 
         if stdout:
-            LOG.info("check the environment success!")
+            LOG.info("Check the environment success!")
             return int(stdout.strip('\n'))
         else:
-            LOG.error(
-                "the host environment is error, stdout:%s, stderr:%s",
-                stdout, stderr)
+            LOG.error("Error checking the host environment, "
+                      "stdout:%s, stderr:%s", stdout, stderr)
         return False
 
     def inject_fault(self):
         with open(self.inject_script, "r") as stdin_file:
-            exit_status, stdout, stderr = self.connection.execute(
+            self.connection.execute(
                 "sudo /bin/sh -s {0}".format(self.service_name),
                 stdin=stdin_file)
 
     def recover(self):
         with open(self.recovery_script, "r") as stdin_file:
-            exit_status, stdout, stderr = self.connection.execute(
+            exit_status, _, _ = self.connection.execute(
                 "sudo /bin/bash -s {0} ".format(self.service_name),
                 stdin=stdin_file)
         if exit_status:
-            LOG.info("Fail to restart service!")
+            LOG.info("Failed to restart service: %s", self.recovery_script)
index d03d044..d67a16b 100644 (file)
@@ -71,7 +71,7 @@ class BaseAttacker(object):
         for attacker_cls in utils.itersubclasses(BaseAttacker):
             if attacker_type == attacker_cls.__attacker_type__:
                 return attacker_cls
-        raise RuntimeError("No such runner_type %s" % attacker_type)
+        raise RuntimeError("No such runner_type: %s" % attacker_type)
 
     def get_script_fullpath(self, path):
         base_path = os.path.dirname(attacker_conf_path)
index 71690c1..6cc0cb2 100644 (file)
@@ -40,7 +40,7 @@ class Director(object):
         nodes = self.context_cfg.get("nodes", None)
         # setup attackers
         if "attackers" in self.scenario_cfg["options"]:
-            LOG.debug("start init attackers...")
+            LOG.debug("Start init attackers...")
             attacker_cfgs = self.scenario_cfg["options"]["attackers"]
             self.attackerMgr = baseattacker.AttackerMgr()
             self.data = self.attackerMgr.init_attackers(attacker_cfgs,
@@ -48,19 +48,19 @@ class Director(object):
 
         # setup monitors
         if "monitors" in self.scenario_cfg["options"]:
-            LOG.debug("start init monitors...")
+            LOG.debug("Start init monitors...")
             monitor_cfgs = self.scenario_cfg["options"]["monitors"]
             self.monitorMgr = basemonitor.MonitorMgr(self.data)
             self.monitorMgr.init_monitors(monitor_cfgs, nodes)
         # setup operations
         if "operations" in self.scenario_cfg["options"]:
-            LOG.debug("start init operations...")
+            LOG.debug("Start init operations...")
             operation_cfgs = self.scenario_cfg["options"]["operations"]
             self.operationMgr = baseoperation.OperationMgr()
             self.operationMgr.init_operations(operation_cfgs, nodes)
         # setup result checker
         if "resultCheckers" in self.scenario_cfg["options"]:
-            LOG.debug("start init resultCheckers...")
+            LOG.debug("Start init resultCheckers...")
             result_check_cfgs = self.scenario_cfg["options"]["resultCheckers"]
             self.resultCheckerMgr = baseresultchecker.ResultCheckerMgr()
             self.resultCheckerMgr.init_ResultChecker(result_check_cfgs, nodes)
@@ -69,7 +69,7 @@ class Director(object):
         if intermediate_variables is None:
             intermediate_variables = {}
         LOG.debug(
-            "the type of current action is %s, the key is %s", type, key)
+            "The type of current action is %s, the key is %s", type, key)
         if type == ActionType.ATTACKER:
             return actionplayers.AttackerPlayer(self.attackerMgr[key], intermediate_variables)
         if type == ActionType.MONITOR:
@@ -80,17 +80,17 @@ class Director(object):
         if type == ActionType.OPERATION:
             return actionplayers.OperationPlayer(self.operationMgr[key],
                                                  intermediate_variables)
-        LOG.debug("something run when creatactionplayer")
+        LOG.debug("The type is not recognized by createActionPlayer")
 
     def createActionRollbacker(self, type, key):
         LOG.debug(
-            "the type of current action is %s, the key is %s", type, key)
+            "The type of current action is %s, the key is %s", type, key)
         if type == ActionType.ATTACKER:
             return actionrollbackers.AttackerRollbacker(self.attackerMgr[key])
         if type == ActionType.OPERATION:
             return actionrollbackers.OperationRollbacker(
                 self.operationMgr[key])
-        LOG.debug("no rollbacker created for %s", key)
+        LOG.debug("No rollbacker created for key: %s", key)
 
     def verify(self):
         result = True
@@ -99,7 +99,7 @@ class Director(object):
         if hasattr(self, 'resultCheckerMgr'):
             result &= self.resultCheckerMgr.verify()
         if result:
-            LOG.debug("monitors are passed")
+            LOG.debug("Monitor results are passed")
         return result
 
     def stopMonitors(self):
@@ -107,12 +107,12 @@ class Director(object):
             self.monitorMgr.wait_monitors()
 
     def knockoff(self):
-        LOG.debug("knock off ....")
+        LOG.debug("Knock off ....")
         while self.executionSteps:
             singleStep = self.executionSteps.pop()
             singleStep.rollback()
 
     def store_result(self, result):
-        LOG.debug("store result ....")
+        LOG.debug("Store result ....")
         if hasattr(self, 'monitorMgr'):
             self.monitorMgr.store_result(result)
index 858d86c..2388507 100755 (executable)
@@ -9,24 +9,23 @@
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
 
-# Start a service and check the service is started
+# Start or restart a service and check the service is started
 
 set -e
 
 service_name=$1
+operation=${2-start} # values are "start" or "restart"
 
-Distributor=$(lsb_release -a | grep "Distributor ID" | awk '{print $3}')
-
-if [ "$Distributor" != "Ubuntu" -a "$service_name" != "keystone" -a "$service_name" != "neutron-server" -a "$service_name" != "haproxy" ]; then
+if [ -f /usr/bin/yum -a "$service_name" != "keystone" -a "$service_name" != "neutron-server" -a "$service_name" != "haproxy" -a "$service_name" != "openvswitch" ]; then
     service_name="openstack-"${service_name}
-elif [ "$Distributor" = "Ubuntu" -a "$service_name" = "keystone" ]; then
+elif [ -f /usr/bin/apt -a "$service_name" = "keystone" ]; then
     service_name="apache2"
 elif [ "$service_name" = "keystone" ]; then
     service_name="httpd"
 fi
 
 if which systemctl 2>/dev/null; then
-    systemctl start $service_name
+    systemctl $operation $service_name
 else
-    service $service_name start
+    service $service_name $operation
 fi
index 50a63f5..f6004c7 100644 (file)
@@ -103,7 +103,7 @@ class BaseMonitor(multiprocessing.Process):
         for monitor in utils.itersubclasses(BaseMonitor):
             if monitor_type == monitor.__monitor_type__:
                 return monitor
-        raise RuntimeError("No such monitor_type %s" % monitor_type)
+        raise RuntimeError("No such monitor_type: %s" % monitor_type)
 
     def get_script_fullpath(self, path):
         base_path = os.path.dirname(monitor_conf_path)
index d0551bf..3b36c76 100644 (file)
@@ -24,7 +24,7 @@ def _execute_shell_command(command):
     output = []
     try:
         output = subprocess.check_output(command, shell=True)
-    except Exception:
+    except Exception:  # pylint: disable=broad-except
         exitcode = -1
         LOG.error("exec command '%s' error:\n ", command, exc_info=True)
 
@@ -45,7 +45,7 @@ class MonitorOpenstackCmd(basemonitor.BaseMonitor):
             self.connection = ssh.SSH.from_node(host,
                                                 defaults={"user": "root"})
             self.connection.wait(timeout=600)
-            LOG.debug("ssh host success!")
+            LOG.debug("ssh host (%s) success!", str(host))
 
         self.check_script = self.get_script_fullpath(
             "ha_tools/check_openstack_cmd.bash")
@@ -61,22 +61,20 @@ class MonitorOpenstackCmd(basemonitor.BaseMonitor):
                 self.cmd = self.cmd + " --insecure"
 
     def monitor_func(self):
-        exit_status = 0
         exit_status, stdout = _execute_shell_command(self.cmd)
-        LOG.debug("Execute command '%s' and the stdout is:\n%s", self.cmd, stdout)
+        LOG.debug("Executed command '%s'. "
+                  "The stdout is:\n%s", self.cmd, stdout)
         if exit_status:
             return False
         return True
 
     def verify_SLA(self):
         outage_time = self._result.get('outage_time', None)
-        LOG.debug("the _result:%s", self._result)
         max_outage_time = self._config["sla"]["max_outage_time"]
         if outage_time > max_outage_time:
             LOG.info("SLA failure: %f > %f", outage_time, max_outage_time)
             return False
         else:
-            LOG.info("the sla is passed")
             return True
 
 
@@ -97,7 +95,7 @@ def _test():    # pragma: no cover
     }
     monitor_configs.append(config)
 
-    p = basemonitor.MonitorMgr()
+    p = basemonitor.MonitorMgr({})
     p.init_monitors(monitor_configs, context)
     p.start_monitors()
     p.wait_monitors()
index dce69f4..971bae1 100644 (file)
@@ -29,7 +29,7 @@ class MultiMonitor(basemonitor.BaseMonitor):
         monitor_cls = basemonitor.BaseMonitor.get_monitor_cls(monitor_type)
 
         monitor_number = self._config.get("monitor_number", 1)
-        for i in range(monitor_number):
+        for _ in range(monitor_number):
             monitor_ins = monitor_cls(self._config, self._context,
                                       self.monitor_data)
             self.monitors.append(monitor_ins)
@@ -70,7 +70,8 @@ class MultiMonitor(basemonitor.BaseMonitor):
         elif "max_recover_time" in self._config["sla"]:
             max_outage_time = self._config["sla"]["max_recover_time"]
         else:
-            raise RuntimeError("monitor max_outage_time config is not found")
+            raise RuntimeError("'max_outage_time' or 'max_recover_time' "
+                               "config is not found")
         self._result = {"outage_time": outage_time}
 
         if outage_time > max_outage_time:
index b0f6f8e..8d2f263 100644 (file)
@@ -25,14 +25,14 @@ class MonitorProcess(basemonitor.BaseMonitor):
 
         self.connection = ssh.SSH.from_node(host, defaults={"user": "root"})
         self.connection.wait(timeout=600)
-        LOG.debug("ssh host success!")
+        LOG.debug("ssh host (%s) success!", str(host))
         self.check_script = self.get_script_fullpath(
             "ha_tools/check_process_python.bash")
         self.process_name = self._config["process_name"]
 
     def monitor_func(self):
         with open(self.check_script, "r") as stdin_file:
-            exit_status, stdout, stderr = self.connection.execute(
+            _, stdout, _ = self.connection.execute(
                 "sudo /bin/sh -s {0}".format(self.process_name),
                 stdin=stdin_file)
 
@@ -45,14 +45,12 @@ class MonitorProcess(basemonitor.BaseMonitor):
         return True
 
     def verify_SLA(self):
-        LOG.debug("the _result:%s", self._result)
         outage_time = self._result.get('outage_time', None)
         max_outage_time = self._config["sla"]["max_recover_time"]
         if outage_time > max_outage_time:
-            LOG.error("SLA failure: %f > %f", outage_time, max_outage_time)
+            LOG.info("SLA failure: %f > %f", outage_time, max_outage_time)
             return False
         else:
-            LOG.info("the sla is passed")
             return True
 
 
@@ -73,7 +71,7 @@ def _test():    # pragma: no cover
     }
     monitor_configs.append(config)
 
-    p = basemonitor.MonitorMgr()
+    p = basemonitor.MonitorMgr({})
     p.init_monitors(monitor_configs, context)
     p.start_monitors()
     p.wait_monitors()
index dcd0fe5..42941c6 100755 (executable)
@@ -34,7 +34,7 @@ class ServiceHA(base.Scenario):
         """scenario setup"""
         nodes = self.context_cfg.get("nodes", None)
         if nodes is None:
-            LOG.error("the nodes info is none")
+            LOG.error("The nodes info is none")
             return
 
         self.attackers = []
@@ -57,17 +57,17 @@ class ServiceHA(base.Scenario):
     def run(self, result):
         """execute the benchmark"""
         if not self.setup_done:
-            LOG.error("The setup not finished!")
+            LOG.error("The setup is not finished!")
             return
 
         self.monitorMgr.start_monitors()
-        LOG.info("HA monitor start!")
+        LOG.info("Monitor '%s' start!", self.__scenario_type__)
 
         for attacker in self.attackers:
             attacker.inject_fault()
 
         self.monitorMgr.wait_monitors()
-        LOG.info("HA monitor stop!")
+        LOG.info("Monitor '%s' stop!", self.__scenario_type__)
 
         sla_pass = self.monitorMgr.verify_SLA()
         for k, v in self.data.items():
index 153bd4b..8640afb 100644 (file)
@@ -152,3 +152,6 @@ IS_PUBLIC = 'is_public'
 # general
 TESTCASE_PRE = 'opnfv_yardstick_'
 TESTSUITE_PRE = 'opnfv_'
+
+# OpenStack cloud default config parameters
+OS_CLOUD_DEFAULT_CONFIG = {'verify': False}
index 68cf0a5..5a83ddb 100644 (file)
@@ -7,19 +7,21 @@
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
 
+import copy
+import logging
 import os
 import sys
-import logging
 
+from cinderclient import client as cinderclient
+from novaclient import client as novaclient
+from glanceclient import client as glanceclient
 from keystoneauth1 import loading
 from keystoneauth1 import session
+from neutronclient.neutron import client as neutronclient
 import shade
 from shade import exc
 
-from cinderclient import client as cinderclient
-from novaclient import client as novaclient
-from glanceclient import client as glanceclient
-from neutronclient.neutron import client as neutronclient
+from yardstick.common import constants
 
 
 log = logging.getLogger(__name__)
@@ -155,8 +157,21 @@ def get_glance_client():    # pragma: no cover
     return glanceclient.Client(get_glance_client_version(), session=sess)
 
 
-def get_shade_client():
-    return shade.openstack_cloud()
+def get_shade_client(**os_cloud_config):
+    """Get Shade OpenStack cloud client
+
+    By default, the input parameters given to "shade.openstack_cloud" method
+    are stored in "constants.OS_CLOUD_DEFAULT_CONFIG". The input parameters
+    passed in this function, "os_cloud_config", will overwrite the default
+    ones.
+
+    :param os_cloud_config: (kwargs) input arguments for
+                            "shade.openstack_cloud" method.
+    :return: ``shade.OpenStackCloud`` object.
+    """
+    params = copy.deepcopy(constants.OS_CLOUD_DEFAULT_CONFIG)
+    params.update(os_cloud_config)
+    return shade.openstack_cloud(**params)
 
 
 # *********************************************
@@ -769,9 +784,8 @@ def list_images(shade_client=None):
 # *********************************************
 #   CINDER
 # *********************************************
-def get_volume_id(volume_name):    # pragma: no cover
-    volumes = get_cinder_client().volumes.list()
-    return next((v.id for v in volumes if v.name == volume_name), None)
+def get_volume_id(shade_client, volume_name):
+    return shade_client.get_volume_id(volume_name)
 
 
 def create_volume(cinder_client, volume_name, volume_size,
index 70ce4ff..c538cee 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from __future__ import absolute_import
-from __future__ import print_function
-import sys
 import logging
 
 import re
 from itertools import product
+import IxNetwork
+
 
 log = logging.getLogger(__name__)
 
@@ -135,7 +134,6 @@ class IxNextgen(object):
             port.append(port0)
 
         cfg = {
-            'py_lib_path': tg_cfg["mgmt-interface"]["tg-config"]["py_lib_path"],
             'machine': tg_cfg["mgmt-interface"]["ip"],
             'port': tg_cfg["mgmt-interface"]["tg-config"]["tcl_port"],
             'chassis': tg_cfg["mgmt-interface"]["tg-config"]["ixchassis"],
@@ -186,7 +184,7 @@ class IxNextgen(object):
             self.set_random_ip_multi_attribute(ip, seeds[1], fixed_bits, random_mask, l3_count)
 
     def add_ip_header(self, params, version):
-        for it, ep, i in self.iter_over_get_lists('/traffic', 'trafficItem', "configElement", 1):
+        for _, ep, i in self.iter_over_get_lists('/traffic', 'trafficItem', "configElement", 1):
             iter1 = (v['outer_l3'] for v in params.values() if str(v['id']) == str(i))
             try:
                 l3 = next(iter1, {})
@@ -194,21 +192,13 @@ class IxNextgen(object):
             except (KeyError, IndexError):
                 continue
 
-            for ip, ip_bits, _ in self.iter_over_get_lists(ep, 'stack', 'field'):
+            for _, ip_bits, _ in self.iter_over_get_lists(ep, 'stack', 'field'):
                 self.set_random_ip_multi_attributes(ip_bits, version, seeds, l3)
 
         self.ixnet.commit()
 
     def _connect(self, tg_cfg):
         self._cfg = self.get_config(tg_cfg)
-
-        sys.path.append(self._cfg["py_lib_path"])
-        # Import IxNetwork after getting ixia lib path
-        try:
-            import IxNetwork
-        except ImportError:
-            raise
-
         self.ixnet = IxNetwork.IxNet()
 
         machine = self._cfg['machine']
@@ -292,7 +282,7 @@ class IxNextgen(object):
             self.update_ether_multi_attribute(ether, str(l2.get('srcmac', "00:00:00:00:00:01")))
 
     def ix_update_ether(self, params):
-        for ti, ep, index in self.iter_over_get_lists('/traffic', 'trafficItem',
+        for _, ep, index in self.iter_over_get_lists('/traffic', 'trafficItem',
                                                       "configElement", 1):
             iter1 = (v['outer_l2'] for v in params.values() if str(v['id']) == str(index))
             try:
@@ -300,7 +290,7 @@ class IxNextgen(object):
             except KeyError:
                 continue
 
-            for ip, ether, _ in self.iter_over_get_lists(ep, 'stack', 'field'):
+            for _, ether, _ in self.iter_over_get_lists(ep, 'stack', 'field'):
                 self.update_ether_multi_attributes(ether, l2)
 
         self.ixnet.commit()
index 5afa415..e0c0db2 100644 (file)
@@ -22,13 +22,13 @@ import time
 
 from oslo_serialization import jsonutils
 from oslo_utils import encodeutils
-import shade
 from shade._heat import event_utils
 
-import yardstick.common.openstack_utils as op_utils
+from yardstick.common import constants as consts
 from yardstick.common import exceptions
 from yardstick.common import template_format
-from yardstick.common import constants as consts
+from yardstick.common import openstack_utils as op_utils
+
 
 log = logging.getLogger(__name__)
 
@@ -41,10 +41,11 @@ _DEPLOYED_STACKS = {}
 class HeatStack(object):
     """Represents a Heat stack (deployed template) """
 
-    def __init__(self, name):
+    def __init__(self, name, os_cloud_config=None):
         self.name = name
         self.outputs = {}
-        self._cloud = shade.openstack_cloud()
+        os_cloud_config = {} if not os_cloud_config else os_cloud_config
+        self._cloud = op_utils.get_shade_client(**os_cloud_config)
         self._stack = None
 
     def _update_stack_tracking(self):
@@ -152,10 +153,12 @@ name (i.e. %s).
         # short hand for resources part of template
         self.resources = self._template['resources']
 
-    def __init__(self, name, template_file=None, heat_parameters=None):
+    def __init__(self, name, template_file=None, heat_parameters=None,
+                 os_cloud_config=None):
         self.name = name
         self.keystone_client = None
         self.heat_parameters = {}
+        self._os_cloud_config = {} if not os_cloud_config else os_cloud_config
 
         # heat_parameters is passed to heat in stack create, empty dict when
         # yardstick creates the template (no get_param in resources part)
@@ -622,7 +625,7 @@ name (i.e. %s).
         log.info("Creating stack '%s' START", self.name)
 
         start_time = time.time()
-        stack = HeatStack(self.name)
+        stack = HeatStack(self.name, os_cloud_config=self._os_cloud_config)
         stack.create(self._template, self.heat_parameters, block, timeout)
 
         if not block:
index 7c980b4..45a3995 100644 (file)
@@ -6,6 +6,7 @@
 # which accompanies this distribution, and is available at
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
+{% set context_name = context_name or "demo" %}
 ---
 # Sample Heat context config with Dummy context
 
@@ -22,9 +23,9 @@ scenarios:
 
 context:
   name: {{ context_name }}
-  image: cirros-0.3.5
-  flavor: cirros256
-  user: cirros
+  image: yardstick-image
+  flavor: yardstick-flavor
+  user: ubuntu
 
   servers:
     athena:
index 153c6a5..b198834 100644 (file)
@@ -25,6 +25,7 @@ class FlagsTestCase(unittest.TestCase):
     def test___init__(self):
         self.assertFalse(self.flags.no_setup)
         self.assertFalse(self.flags.no_teardown)
+        self.assertEqual({'verify': False}, self.flags.os_cloud_config)
 
     def test___init__with_flags(self):
         flags = base.Flags(no_setup=True)
@@ -32,10 +33,12 @@ class FlagsTestCase(unittest.TestCase):
         self.assertFalse(flags.no_teardown)
 
     def test_parse(self):
-        self.flags.parse(no_setup=True, no_teardown="False")
+        self.flags.parse(no_setup=True, no_teardown='False',
+                         os_cloud_config={'verify': True})
 
         self.assertTrue(self.flags.no_setup)
-        self.assertEqual(self.flags.no_teardown, "False")
+        self.assertEqual('False', self.flags.no_teardown)
+        self.assertEqual({'verify': True}, self.flags.os_cloud_config)
 
     def test_parse_forbidden_flags(self):
         self.flags.parse(foo=42)
index 1d491fe..ebb1d69 100644 (file)
@@ -234,7 +234,7 @@ class HeatContextTestCase(unittest.TestCase):
 
     @mock.patch.object(os.path, 'exists', return_value=False)
     @mock.patch.object(ssh.SSH, 'gen_keys')
-    @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
+    @mock.patch.object(heat, 'HeatTemplate')
     def test_deploy(self, mock_template, mock_genkeys, mock_path_exists):
         self.test_context._name = 'foo'
         self.test_context._task_id = '1234567890'
@@ -245,9 +245,10 @@ class HeatContextTestCase(unittest.TestCase):
         self.test_context.get_neutron_info = mock.MagicMock()
         self.test_context.deploy()
 
-        mock_template.assert_called_with('foo-12345678',
-                                         '/bar/baz/some-heat-file',
-                                         {'image': 'cirros'})
+        mock_template.assert_called_with(
+            'foo-12345678', template_file='/bar/baz/some-heat-file',
+            heat_parameters={'image': 'cirros'},
+            os_cloud_config=self.test_context._flags.os_cloud_config)
         self.assertIsNotNone(self.test_context.stack)
         key_filename = ''.join(
             [consts.YARDSTICK_ROOT_PATH,
index 81bcd8c..cc19d98 100644 (file)
 from oslo_utils import uuidutils
 import unittest
 import mock
-
+import shade
 from shade import exc
+
+from yardstick.common import constants
 from yardstick.common import openstack_utils
 
 
@@ -35,6 +37,29 @@ class GetHeatApiVersionTestCase(unittest.TestCase):
             self.assertEqual(api_version, expected_result)
 
 
+class GetShadeClientTestCase(unittest.TestCase):
+
+    @mock.patch.object(shade, 'openstack_cloud', return_value='os_client')
+    def test_get_shade_client(self, mock_openstack_cloud):
+        os_cloud_config = {'param1': True, 'param2': 'value2'}
+        self.assertEqual('os_client',
+                         openstack_utils.get_shade_client(**os_cloud_config))
+        os_cloud_config.update(constants.OS_CLOUD_DEFAULT_CONFIG)
+        mock_openstack_cloud.assert_called_once_with(**os_cloud_config)
+
+        mock_openstack_cloud.reset_mock()
+        os_cloud_config = {'verify': True, 'param2': 'value2'}
+        self.assertEqual('os_client',
+                         openstack_utils.get_shade_client(**os_cloud_config))
+        mock_openstack_cloud.assert_called_once_with(**os_cloud_config)
+
+    @mock.patch.object(shade, 'openstack_cloud', return_value='os_client')
+    def test_get_shade_client_no_parameters(self, mock_openstack_cloud):
+        self.assertEqual('os_client', openstack_utils.get_shade_client())
+        mock_openstack_cloud.assert_called_once_with(
+            **constants.OS_CLOUD_DEFAULT_CONFIG)
+
+
 class DeleteNeutronNetTestCase(unittest.TestCase):
 
     def setUp(self):
@@ -511,3 +536,25 @@ class GetFlavorTestCase(unittest.TestCase):
                                             'flavor_name_or_id')
         mock_logger.error.assert_called_once()
         self.assertIsNone(output)
+
+# *********************************************
+#   CINDER
+# *********************************************
+
+
+class GetVolumeIDTestCase(unittest.TestCase):
+
+    def test_get_volume_id(self):
+        self.mock_shade_client = mock.Mock()
+        _uuid = uuidutils.generate_uuid()
+        self.mock_shade_client.get_volume_id.return_value = _uuid
+        output = openstack_utils.get_volume_id(self.mock_shade_client,
+                                               'volume_name')
+        self.assertEqual(_uuid, output)
+
+    def test_get_volume_id_None(self):
+        self.mock_shade_client = mock.Mock()
+        self.mock_shade_client.get_volume_id.return_value = None
+        output = openstack_utils.get_volume_id(self.mock_shade_client,
+                                               'volume_name')
+        self.assertIsNone(output)
diff --git a/yardstick/tests/unit/common/test_packages.py b/yardstick/tests/unit/common/test_packages.py
new file mode 100644 (file)
index 0000000..ba59a30
--- /dev/null
@@ -0,0 +1,88 @@
+# Copyright (c) 2018 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import mock
+from pip import exceptions as pip_exceptions
+from pip.operations import freeze
+import unittest
+
+from yardstick.common import packages
+
+
+class PipExecuteActionTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self._mock_pip_main = mock.patch.object(packages, '_pip_main')
+        self.mock_pip_main = self._mock_pip_main.start()
+        self.mock_pip_main.return_value = 0
+        self._mock_freeze = mock.patch.object(freeze, 'freeze')
+        self.mock_freeze = self._mock_freeze.start()
+        self.addCleanup(self._cleanup)
+
+    def _cleanup(self):
+        self._mock_pip_main.stop()
+        self._mock_freeze.stop()
+
+    def test_pip_execute_action(self):
+        self.assertEqual(0, packages._pip_execute_action('test_package'))
+
+    def test_remove(self):
+        self.assertEqual(0, packages._pip_execute_action('test_package',
+                                                         action='uninstall'))
+
+    def test_install(self):
+        self.assertEqual(0, packages._pip_execute_action(
+            'test_package', action='install', target='temp_dir'))
+
+    def test_pip_execute_action_error(self):
+        self.mock_pip_main.return_value = 1
+        self.assertEqual(1, packages._pip_execute_action('test_package'))
+
+    def test_pip_execute_action_exception(self):
+        self.mock_pip_main.side_effect = pip_exceptions.PipError
+        self.assertEqual(1, packages._pip_execute_action('test_package'))
+
+    def test_pip_list(self):
+        pkg_input = [
+            'XStatic-Rickshaw==1.5.0.0',
+            'xvfbwrapper==0.2.9',
+            '-e git+https://git.opnfv.org/yardstick@50773a24afc02c9652b662ecca'
+            '2fc5621ea6097a#egg=yardstick',
+            'zope.interface==4.4.3'
+        ]
+        pkg_dict = {
+            'XStatic-Rickshaw': '1.5.0.0',
+            'xvfbwrapper': '0.2.9',
+            'yardstick': '50773a24afc02c9652b662ecca2fc5621ea6097a',
+            'zope.interface': '4.4.3'
+        }
+        self.mock_freeze.return_value = pkg_input
+
+        pkg_output = packages.pip_list()
+        for pkg_name, pkg_version in pkg_output.items():
+            self.assertEqual(pkg_dict.get(pkg_name), pkg_version)
+
+    def test_pip_list_single_package(self):
+        pkg_input = [
+            'XStatic-Rickshaw==1.5.0.0',
+            'xvfbwrapper==0.2.9',
+            '-e git+https://git.opnfv.org/yardstick@50773a24afc02c9652b662ecca'
+            '2fc5621ea6097a#egg=yardstick',
+            'zope.interface==4.4.3'
+        ]
+        self.mock_freeze.return_value = pkg_input
+
+        pkg_output = packages.pip_list(pkg_name='xvfbwrapper')
+        self.assertEqual(1, len(pkg_output))
+        self.assertEqual(pkg_output.get('xvfbwrapper'), '0.2.9')
index fe750e5..7ca2f0f 100644 (file)
@@ -13,8 +13,9 @@
 # limitations under the License.
 #
 
-import unittest
 import mock
+import IxNetwork
+import unittest
 
 from yardstick.network_services.libs.ixia_libs.IxNet.IxNet import IxNextgen
 from yardstick.network_services.libs.ixia_libs.IxNet.IxNet import IP_VERSION_4
@@ -30,15 +31,20 @@ class TestIxNextgen(unittest.TestCase):
         ixnet_gen = IxNextgen()
         self.assertIsNone(ixnet_gen._bidir)
 
-    @mock.patch("yardstick.network_services.libs.ixia_libs.IxNet.IxNet.sys")
-    def test_connect(self, *args):
-
+    @mock.patch.object(IxNetwork, 'IxNet')
+    def test_connect(self, mock_ixnet):
+        ixnet_instance = mock.Mock()
+        mock_ixnet.return_value = ixnet_instance
         ixnet_gen = IxNextgen()
-        ixnet_gen.get_config = mock.MagicMock()
-        ixnet_gen.get_ixnet = mock.MagicMock()
+        with mock.patch.object(ixnet_gen, 'get_config') as mock_config:
+            mock_config.return_value = {'machine': 'machine_fake',
+                                        'port': 'port_fake',
+                                        'version': 12345}
+            ixnet_gen._connect(mock.ANY)
 
-        self.assertRaises(ImportError, ixnet_gen._connect,
-                          {"py_lib_path": "/tmp"})
+        ixnet_instance.connect.assert_called_once_with(
+            'machine_fake', '-port', 'port_fake', '-version', '12345')
+        mock_config.assert_called_once()
 
     def test_clear_ixia_config(self):
         ixnet = mock.MagicMock()
@@ -655,13 +661,11 @@ class TestIxNextgen(unittest.TestCase):
                     "version": "test3",
                     "ixchassis": "test4",
                     "tcl_port": "test5",
-                    "py_lib_path": "test6",
                 },
             }
         }
 
         expected = {
-            'py_lib_path': 'test6',
             'machine': 'test1',
             'port': 'test5',
             'chassis': 'test4',
index 9598eeb..3ec59a3 100644 (file)
@@ -17,6 +17,7 @@ import shade
 import unittest
 
 from yardstick.benchmark.contexts import node
+from yardstick.common import constants
 from yardstick.common import exceptions
 from yardstick.orchestrator import heat
 
@@ -53,6 +54,14 @@ class HeatStackTestCase(unittest.TestCase):
         self._mock_stack_get.stop()
         heat._DEPLOYED_STACKS = {}
 
+    @mock.patch.object(shade, 'openstack_cloud')
+    def test__init(self, mock_openstack_cloud):
+        os_cloud_config = {'key': 'value'}
+        heatstack = heat.HeatStack('name', os_cloud_config=os_cloud_config)
+        self.assertEqual('name', heatstack.name)
+        os_cloud_config.update(constants.OS_CLOUD_DEFAULT_CONFIG)
+        mock_openstack_cloud.assert_called_once_with(**os_cloud_config)
+
     def test_create(self):
         template = {'tkey': 'tval'}
         heat_parameters = {'pkey': 'pval'}
@@ -192,7 +201,9 @@ class HeatStackTestCase(unittest.TestCase):
 class HeatTemplateTestCase(unittest.TestCase):
 
     def setUp(self):
-        self.template = heat.HeatTemplate('test')
+        self._os_cloud_config = {'key1': 'value1'}
+        self.template = heat.HeatTemplate(
+            'test', os_cloud_config=self._os_cloud_config)
 
     def test_add_tenant_network(self):
         self.template.add_network('some-network')
@@ -337,8 +348,12 @@ class HeatTemplateTestCase(unittest.TestCase):
 
     def test_create_not_block(self):
         heat_stack = mock.Mock()
-        with mock.patch.object(heat, 'HeatStack', return_value=heat_stack):
+        with mock.patch.object(heat, 'HeatStack', return_value=heat_stack) \
+                as mock_heatstack:
             ret = self.template.create(block=False)
+
+        mock_heatstack.assert_called_once_with(
+            self.template.name, os_cloud_config=self.template._os_cloud_config)
         heat_stack.create.assert_called_once_with(
             self.template._template, self.template.heat_parameters, False,
             3600)