Merge "assertTrue(mock.called) -> mock.assert_called"
authorRodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>
Mon, 12 Mar 2018 09:53:40 +0000 (09:53 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Mon, 12 Mar 2018 09:53:40 +0000 (09:53 +0000)
49 files changed:
ansible/roles/convert_openrc/tasks/main.yml
ansible/roles/download_l2fwd/defaults/main.yml [new file with mode: 0644]
ansible/roles/download_l2fwd/tasks/main.yml [new file with mode: 0644]
ansible/roles/infra_check_requirements/tasks/main.yml
ansible/roles/infra_create_network/tasks/create_xml.yml [moved from ansible/roles/infra_create_network/tasks/create_xml.yaml with 85% similarity]
ansible/roles/infra_create_network/tasks/main.yml
ansible/roles/infra_create_vms/tasks/configure_vm.yml
ansible/roles/infra_create_vms/tasks/create_interfaces.yml
ansible/roles/infra_create_vms/tasks/main.yml
ansible/ubuntu_server_cloudimg_modify.yml
docs/testing/developer/devguide/devguide_nsb_prox.rst
docs/testing/user/userguide/11-nsb-overview.rst
etc/infra/infra_deploy.yaml.sample
etc/yardstick/nodes/fuel_baremetal/pod.yaml
samples/MoongenL2fwd.yaml [new file with mode: 0644]
samples/MoongenTestPMD.yaml [new file with mode: 0644]
samples/ping-mixed-network.yaml [new file with mode: 0644]
samples/ping-one-exising-network.yaml [new file with mode: 0644]
samples/ping-two-exising-network.yaml [new file with mode: 0644]
samples/vnf_samples/nsut/prox/tc_prox_baremetal_l2fwd-2.yaml
samples/vnf_samples/nsut/prox/tc_prox_baremetal_l2fwd-4.yaml
tests/ci/prepare_env.sh
tests/opnfv/test_suites/opnfv_k8-nosdn-lb_ceph-noha_daily.yaml [new file with mode: 0644]
tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py
yardstick/benchmark/contexts/heat.py
yardstick/benchmark/contexts/model.py
yardstick/benchmark/core/report.py
yardstick/benchmark/core/task.py
yardstick/benchmark/scenarios/availability/ha_tools/nova/add_server_to_existing_secgroup.bash [new file with mode: 0644]
yardstick/benchmark/scenarios/availability/ha_tools/nova/get_server_privateip.bash [new file with mode: 0644]
yardstick/benchmark/scenarios/availability/ha_tools/nova/remove_server_from_secgroup.bash [new file with mode: 0644]
yardstick/benchmark/scenarios/availability/operation_conf.yaml
yardstick/benchmark/scenarios/networking/moongen_testpmd.bash [new file with mode: 0644]
yardstick/benchmark/scenarios/networking/moongen_testpmd.py [new file with mode: 0644]
yardstick/benchmark/scenarios/storage/fio.py
yardstick/common/constants.py
yardstick/common/exceptions.py
yardstick/network_services/constants.py
yardstick/network_services/traffic_profile/prox_binsearch.py
yardstick/network_services/vnf_generic/vnf/prox_helpers.py
yardstick/network_services/vnf_generic/vnf/prox_vnf.py
yardstick/network_services/vnf_generic/vnf/sample_vnf.py
yardstick/network_services/vnf_generic/vnf/vnf_ssh_helper.py
yardstick/orchestrator/heat.py
yardstick/tests/unit/benchmark/contexts/test_heat.py
yardstick/tests/unit/benchmark/contexts/test_model.py
yardstick/tests/unit/benchmark/scenarios/networking/test_moongen_testpmd.py [new file with mode: 0644]
yardstick/tests/unit/benchmark/scenarios/storage/test_fio.py
yardstick/tests/unit/orchestrator/test_heat.py

index be621f0..00aa136 100644 (file)
@@ -18,7 +18,7 @@
 - debug: var=openrc
 
 - set_fact:
-    yardstick_url_ip: "{{ openrc.OS_AUTH_URL|urlsplit|attr('hostname') }}"
+    yardstick_url_ip: "{{ openrc.OS_AUTH_URL|urlsplit('hostname') }}"
 
 - debug: var=yardstick_url_ip
 
diff --git a/ansible/roles/download_l2fwd/defaults/main.yml b/ansible/roles/download_l2fwd/defaults/main.yml
new file mode 100644 (file)
index 0000000..1bc76ef
--- /dev/null
@@ -0,0 +1,4 @@
+---
+l2fwd_url: "http://artifacts.opnfv.org/yardstick/third-party/l2fwd.tar"
+l2fwd_file: "l2fwd.tar"
+l2fwd_dest: "/home"
diff --git a/ansible/roles/download_l2fwd/tasks/main.yml b/ansible/roles/download_l2fwd/tasks/main.yml
new file mode 100644 (file)
index 0000000..7f2ea25
--- /dev/null
@@ -0,0 +1,28 @@
+# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others.
+#
+# 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.
+---
+- file:
+    path: "{{ l2fwd_dest }}"
+    state: directory
+
+- name: fetch dpdk
+  get_url:
+    url: "{{ l2fwd_url }}"
+    dest: "{{ l2fwd_dest }}"
+
+- unarchive:
+    src: "{{ l2fwd_dest }}/{{ l2fwd_file }}"
+    dest: "{{ l2fwd_dest }}/"
+    copy: no
+    mode: 0777
index 8d05bbd..a11bc56 100644 (file)
     msg: "Failed, not enough CPU, required: {{ vcpu_t }}, available {{ ansible_processor_vcpus }}"
   when: ansible_processor_vcpus < vcpu_t|int
 
+- name: Define default network counter
+  set_fact:
+    num_default_network_detected: 0
+
+- name: Increment counter for every default network detected
+  set_fact:
+    num_default_network_detected: "{{ num_default_network_detected|int + 1 }}"
+  when:
+    - item.default_gateway is defined
+    - item.default_gateway == True
+  with_items: "{{infra_deploy_vars.networks}}"
+
+- name: Fail if more than 1 or 0 default networks
+  fail:
+    msg: "Failed, there must be 1 default network: {{ num_default_network_detected }} detected"
+  when: num_default_network_detected|int != 1
 
 - name: Fail if not enough Disk space
   set_fact:
     xpath: /network
     add_children:
       - name: "{{ item.name }}"
+      - forward:
+          mode: nat
       - bridge
       - ip
     pretty_print: yes
 
+- name: Add new children nodes to "forward" node
+  xml:
+    path: "{{ xml_file }}"
+    xpath: /network/forward
+    add_children:
+      - nat
+    pretty_print: yes
+
+- name: Add new children nodes to "nat" node
+  xml:
+    path: "{{ xml_file }}"
+    xpath: /network/forward/nat
+    add_children:
+      - port:
+          start: "1024"
+          end: "65535"
+    pretty_print: yes
+
 - name: Add "name" attribute to "bridge" node
   xml:
     path: "{{ xml_file }}"
index eba4a3a..025a775 100644 (file)
@@ -18,5 +18,5 @@
     name: infra_deploy_vars
 
 - name: Create XML file
-  include_tasks: create_xml.yaml
+  include_tasks: create_xml.yml
   with_items: "{{ infra_deploy_vars.networks }}"
index 10201cf..7419fd5 100644 (file)
 
 - name: Populate network-config and add interface to xml file
   include_tasks: create_interfaces.yml
-  extra_vars: "{{ network_config, xml_file , slot_address, mac_address_counter }}"
+  extra_vars: "{{ network_config xml_file slot_address mac_address_counter }}"
   loop_control:
     loop_var: interface_item
   with_items: "{{ node_item.interfaces }}"
   shell: >
     qemu-img convert -O qcow2 {{ node_item.image }} {{ image_dir+node_item.hostname+'.qcow2' }}
 
-- name: Copy and convert the ubuntu image
+- name: Resize image
   shell: >
-    qemu-img resize {{ image_dir+node_item.hostname+'.qcow2' }} {{ node_item.disk }}MB
+    qemu-img resize {{ image_dir+node_item.hostname+'.qcow2' }} {{ node_item.disk }}M
 
 - name: Define the VMs
   virt:
index 124421b..34bfd1b 100644 (file)
           addresses:
             - {{ interface_item.ip }}/{{ interface_item.netmask }}
 
+- name: Add default gateway
+  blockinfile:
+    path: "{{ network_config }}"
+    insertafter: "{{ interface_item.ip }}"
+    marker: "MARKER"
+    block: |2
+          gateway4: {{ default_bridge.host_ip }}
+  when:
+    - default_bridge is defined
+    - default_bridge.name == interface_item.network
 
 - name: Remove the marker introduced in network-data
   lineinfile:
index 62a023e..4d47f44 100644 (file)
 - set_fact:
     mac_address_counter: 0
 
+- set_fact:
+    default_bridge: "{{ item }}"
+  when:
+    - item.default_gateway is defined
+    - item.default_gateway == True
+  with_items: "{{ infra_deploy_vars.networks }}"
+
 - name: Create XML file
   include_tasks: configure_vm.yml
-  extra_vars: "{{ mac_address_counter }}"
   loop_control:
     loop_var: node_item
   with_items: "{{ infra_deploy_vars.nodes }}"
index 099d580..90235cc 100644 (file)
@@ -27,6 +27,7 @@
     - modify_cloud_config
     - role: set_package_installer_proxy
       when: proxy_env is defined and proxy_env
+    - download_l2fwd
     - install_image_dependencies
     - download_unixbench
     - install_unixbench
index fc533b2..2262841 100755 (executable)
@@ -251,9 +251,11 @@ Now let's examine the components of the file in detail
    In this case it is ``handle_l2fwd-2.cfg``
 
    A number of additional parameters can be added. This example
-   is taken from VPE::
+   is for VPE::
 
     options:
+      interface_speed_gbps: 10
+
       vnf__0:
         prox_path: /opt/nsb_bin/prox
         prox_config: ``configs/handle_vpe-4.cfg``
@@ -267,6 +269,12 @@ Now let's examine the components of the file in detail
           ``configs/vpe_rules.lua`` : ````
         prox_generate_parameter: True
 
+   ``interface_speed_gbps`` - this specifies the speed of the interface
+   in Gigabits Per Second. This is used to calculate pps(packets per second).
+   If the interfaces are of different speeds, then this specifies the speed
+   of the slowest interface. This parameter is optional. If omitted the
+   interface speed defaults to 10Gbps.
+
    ``prox_files`` - this specified that a number of addition files
    need to be provided for the test to run correctly. This files
    could provide routing information,hashing information or a
index 8ce90f6..332dba4 100644 (file)
@@ -197,7 +197,9 @@ VNFs supported for chracterization:
 1. CGNAPT - Carrier Grade Network Address and port Translation
 2. vFW - Virtual Firewall
 3. vACL - Access Control List
-5. Prox - Packet pROcessing eXecution engine:
-    - VNF can act as Drop, Basic Forwarding (no touch), L2 Forwarding (change MAC), GRE encap/decap, Load balance based on packet fields, Symmetric load balancing,
+4. Prox - Packet pROcessing eXecution engine:
+    - VNF can act as Drop, Basic Forwarding (no touch),
+      L2 Forwarding (change MAC), GRE encap/decap, Load balance based on
+      packet fields, Symmetric load balancing
     - QinQ encap/decap IPv4/IPv6, ARP, QoS, Routing, Unmpls, Policing, ACL
-6. UDP_Replay
+5. UDP_Replay
index bf07a01..8ed7936 100644 (file)
@@ -31,5 +31,11 @@ nodes:
 
 networks:
   - name: management
+    default_gateway: True
     host_ip: 192.168.1.1
     netmask: 255.255.255.0
+
+  - name: traffic
+    default_gateway: False  # This parameter is not mandatory, default value: False
+    host_ip: 192.20.1.1
+    netmask: 255.255.255.0
index 5ce5552..301433d 100644 (file)
@@ -49,3 +49,16 @@ nodes:
     ip: ip5
     user: node_username
     key_filename: node_keyfile
+-
+    name: node6
+    role: Opendaylight
+    ip: ip6
+    user: node_username
+    key_filename: node_keyfile
+-
+    name: node7
+    role: Gateway
+    ip: ip7
+    user: node_username
+    key_filename: node_keyfile
+
diff --git a/samples/MoongenL2fwd.yaml b/samples/MoongenL2fwd.yaml
new file mode 100644 (file)
index 0000000..8c00bfe
--- /dev/null
@@ -0,0 +1,96 @@
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd and others.
+# 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.
+
+# VSPERF specific configuration file for execution of RFC2544 throughput
+# traffic. Traffic executed by traffic generator is forwarded directly
+# between interfaces connected to the traffic generator. So test will only
+# benchmark the performance of OVS external bridge at controller node.
+# Details about supported test options and test case execution can be
+# found in VSPERF documentation:
+#
+#   http://artifacts.opnfv.org/vswitchperf/docs/userguide/yardstick.html
+
+schema: "yardstick:task:0.1"
+
+scenarios:
+{% for multistream in [1, 1000] %}
+-
+  type: MoongenTestPMD
+  options:
+    multistream: {{multistream}}
+    frame_size: 1024
+    testpmd_queue: 2
+    trafficgen_port1: 'ens4'
+    trafficgen_port2: 'ens5'
+    moongen_host_user: 'root'
+    moongen_host_passwd: 'root'
+    moongen_host_ip: '192.168.37.2'
+    moongen_dir: '/home/lua-trafficgen'
+    moongen_runBidirec: 'true'
+    Package_Loss: 0
+    SearchRuntime: 60
+    moongen_port1_mac: '88:cf:98:2f:4d:ed'
+    moongen_port2_mac: '88:cf:98:2f:4d:ee'
+    forward_type: 'l2fwd'
+
+  host: testpmd.demo
+
+  runner:
+    type: Sequence
+    scenario_option_name: frame_size
+    sequence:
+    - 64
+
+  sla:
+    # The throughput SLA (or any other SLA) cannot be set to a meaningful
+    # value without knowledge of the server and networking environment,
+    # possibly including prior testing in that environment to establish
+    # a baseline SLA level under well-understood circumstances.
+    throughput_rx_mpps: 0.5
+{% endfor %}
+
+context:
+  name: demo
+  image: yardstick-image
+  flavor:
+    vcpus: 10
+    ram: 20480
+    disk: 6
+    extra_specs:
+      hw:mem_page_size: "1GB"
+      hw:cpu_policy: "dedicated"
+      hw:vif_multiqueue_enabled: "true"
+  user: ubuntu
+
+  placement_groups:
+    pgrp1:
+      policy: "availability"
+
+  servers:
+    testpmd:
+      floating_ip: true
+      placement: "pgrp1"
+
+  networks:
+    test:
+      cidr: '10.0.1.0/24'
+    test2:
+      cidr: '10.0.2.0/24'
+      gateway_ip: 'null'
+      port_security_enabled: False
+      enable_dhcp: 'false'
+    test3:
+      cidr: '10.0.3.0/24'
+      gateway_ip: 'null'
+      port_security_enabled: False
+      enable_dhcp: 'false'
diff --git a/samples/MoongenTestPMD.yaml b/samples/MoongenTestPMD.yaml
new file mode 100644 (file)
index 0000000..b389a19
--- /dev/null
@@ -0,0 +1,106 @@
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd and others.
+# 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.
+
+# VSPERF specific configuration file for execution of RFC2544 throughput
+# traffic. Traffic executed by traffic generator is forwarded directly
+# between interfaces connected to the traffic generator. So test will only
+# benchmark the performance of OVS external bridge at controller node.
+# Details about supported test options and test case execution can be
+# found in VSPERF documentation:
+#
+#   http://artifacts.opnfv.org/vswitchperf/docs/userguide/yardstick.html
+
+schema: "yardstick:task:0.1"
+
+scenarios:
+{% for multistream in [1, 1000] %}
+-
+  type: MoongenTestPMD
+  options:
+    multistream: {{multistream}}
+    frame_size: 1024
+    testpmd_queue: 2
+    trafficgen_port1: 'ens5'
+    trafficgen_port2: 'ens6'
+    moongen_host_user: 'root'
+    moongen_host_passwd: 'root'
+    moongen_host_ip: '192.168.37.2'
+    moongen_dir: '/home/lua-trafficgen'
+    moongen_runBidirec: 'true'
+    Package_Loss: 0
+    SearchRuntime: 60
+    moongen_port1_mac: '88:cf:98:2f:4d:ed'
+    moongen_port2_mac: '88:cf:98:2f:4d:ee'
+    forward_type: 'testpmd'
+
+  host: testpmd.demo
+
+  runner:
+    type: Sequence
+    scenario_option_name: frame_size
+    sequence:
+    - 64
+
+  sla:
+    # The throughput SLA (or any other SLA) cannot be set to a meaningful
+    # value without knowledge of the server and networking environment,
+    # possibly including prior testing in that environment to establish
+    # a baseline SLA level under well-understood circumstances.
+    throughput_rx_mpps: 0.5
+{% endfor %}
+
+context:
+  name: demo
+  #image: yardstick-image
+  image: yardstick-nsb-image
+  flavor:
+    vcpus: 10
+    ram: 20480
+    disk: 6
+    extra_specs:
+      hw:mem_page_size: "1GB"
+      hw:cpu_policy: "dedicated"
+      hw:vif_multiqueue_enabled: "true"
+  user: ubuntu
+
+  placement_groups:
+    pgrp1:
+      policy: "availability"
+
+  servers:
+    testpmd:
+      floating_ip: true
+      placement: "pgrp1"
+
+  networks:
+    test:
+      cidr: '10.0.1.0/24'
+      provider: "sriov"
+      physical_network: "sriov2"
+      segmentation_id: "1063"
+    test2:
+      cidr: '10.0.2.0/24'
+      gateway_ip: 'null'
+      provider: "sriov"
+      physical_network: "sriov2"
+      segmentation_id: "1061"
+      #port_security_enabled: False
+      enable_dhcp: 'false'
+    test3:
+      cidr: '10.0.3.0/24'
+      provider: "sriov"
+      physical_network: "sriov2"
+      segmentation_id: "1062"
+      gateway_ip: 'null'
+      #port_security_enabled: False
+      enable_dhcp: 'false'
diff --git a/samples/ping-mixed-network.yaml b/samples/ping-mixed-network.yaml
new file mode 100644 (file)
index 0000000..76e05c9
--- /dev/null
@@ -0,0 +1,65 @@
+##############################################################################
+## Copyright (c) 2018 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
+###############################################################################
+---
+# Sample benchmark task config file
+# measure network latency using ping
+# This test case sample uses existing network to be public network,
+# and also create the private network by heat like normal ping.
+
+schema: "yardstick:task:0.1"
+
+{% set public_net = public_net or 'public' %}
+{% set public_subnet = public_subnet or 'public_subnet' %}
+{% set provider = provider or none %}
+{% set physical_network = physical_network or 'physnet1' %}
+{% set segmentation_id = segmentation_id or none %}
+
+scenarios:
+-
+  type: Ping
+  options:
+    packetsize: 200
+  host: athena.demo
+  target: ares.demo
+
+  runner:
+    type: Duration
+    duration: 60
+    interval: 1
+
+  sla:
+    max_rtt: 10
+    action: monitor
+
+context:
+  name: demo
+  image: yardstick-image
+  flavor: yardstick-flavor
+  user: ubuntu
+
+  servers:
+    athena:
+    ares:
+
+  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 %}
+
+    {{ public_net }}:
+      net_flags:
+        is_existing: true
+        is_public: true
+      subnet: {{ public_subnet }}
diff --git a/samples/ping-one-exising-network.yaml b/samples/ping-one-exising-network.yaml
new file mode 100644 (file)
index 0000000..9e33148
--- /dev/null
@@ -0,0 +1,50 @@
+##############################################################################
+## Copyright (c) 2018 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
+###############################################################################
+---
+# Sample benchmark task config file
+# measure network latency using ping
+# This sample use one existing network as both public network and private network.
+
+schema: "yardstick:task:0.1"
+
+{% set public_net = public_net or 'public' %}
+{% set public_subnet = public_subnet or 'public_subnet' %}
+
+scenarios:
+-
+  type: Ping
+  options:
+    packetsize: 200
+  host: athena.demo
+  target: ares.demo
+
+  runner:
+    type: Duration
+    duration: 60
+    interval: 1
+
+  sla:
+    max_rtt: 10
+    action: monitor
+
+context:
+  name: demo
+  image: yardstick-image
+  flavor: yardstick-flavor
+  user: ubuntu
+
+  servers:
+    athena:
+    ares:
+
+  networks:
+    {{ public_net }}:
+      net_flags:
+        is_existing: true
+      subnet: {{ public_subnet }}
diff --git a/samples/ping-two-exising-network.yaml b/samples/ping-two-exising-network.yaml
new file mode 100644 (file)
index 0000000..adea43e
--- /dev/null
@@ -0,0 +1,58 @@
+##############################################################################
+## Copyright (c) 2018 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
+###############################################################################
+---
+# Sample benchmark task config file
+# measure network latency using ping
+# This sample use two existing network, one as public network to replace for
+# floating ip, one as private network to ping between VMs.
+
+schema: "yardstick:task:0.1"
+
+{% set private_net = private_net or 'private' %}
+{% set private_subnet = private_subnet or 'private_subnet' %}
+{% set public_net = public_net or 'public' %}
+{% set public_subnet = public_subnet or 'public_subnet' %}
+
+scenarios:
+-
+  type: Ping
+  options:
+    packetsize: 200
+  host: athena.demo
+  target: ares.demo
+
+  runner:
+    type: Duration
+    duration: 60
+    interval: 1
+
+  sla:
+    max_rtt: 10
+    action: monitor
+
+context:
+  name: demo
+  image: yardstick-image
+  flavor: yardstick-flavor
+  user: ubuntu
+
+  servers:
+    athena:
+    ares:
+
+  networks:
+    {{ private_net }}:
+      net_flags:
+        is_existing: true
+      subnet: {{ private_subnet }}
+    {{ public_net }}:
+      net_flags:
+        is_existing: true
+        is_public: true
+      subnet: {{ public_subnet }}
index b1fef6d..69778ed 100644 (file)
@@ -26,6 +26,8 @@ scenarios:
     vnf__0: vnf_0.yardstick
 
   options:
+    interface_speed_gbps: 10
+
     vnf__0:
       prox_path: /opt/nsb_bin/prox
       prox_config: "configs/handle_l2fwd-2.cfg"
index e17c5c2..ab067a8 100644 (file)
@@ -26,6 +26,8 @@ scenarios:
     vnf__0: vnf_0.yardstick
 
   options:
+    interface_speed_gbps: 10
+
     vnf__0:
       prox_path: /opt/nsb_bin/prox
       prox_config: "configs/handle_l2fwd-4.cfg"
index 886e50e..d7c60d4 100755 (executable)
@@ -72,10 +72,12 @@ if [ "$INSTALLER_TYPE" == "fuel" ]; then
 
     # update "ip" according to the CI env
     ssh -l ubuntu "${INSTALLER_IP}" -i ${SSH_KEY} ${ssh_options} \
-         "sudo salt -C 'ctl* or cmp*' grains.get fqdn_ip4  --out yaml">node_info
+         "sudo salt -C 'ctl* or cmp* or odl01* or gtw*' grains.get fqdn_ip4  --out yaml">node_info
 
-    controller_ips=($(awk '/ctl/{getline; print $2} < node_info'))
-    compute_ips=($(awk '/cmp/{getline; print $2} < node_info'))
+    controller_ips=($(awk '/ctl/{getline; print $2}' < node_info))
+    compute_ips=($(awk '/cmp/{getline; print $2}' < node_info))
+    odl_ip=($(awk '/odl01/{getline; print $2}' < node_info))
+    gateway_ip=($(awk '/gtw/{getline; print $2}' < node_info))
 
     if [[ ${controller_ips[0]} ]]; then
         sed -i "s|ip1|${controller_ips[0]}|" "${pod_yaml}"
@@ -92,6 +94,12 @@ if [ "$INSTALLER_TYPE" == "fuel" ]; then
     if [[ ${compute_ips[1]} ]]; then
         sed -i "s|ip5|${compute_ips[1]}|" "${pod_yaml}"
     fi
+    if [[ ${odl_ip[0]} ]]; then
+        sed -i "s|ip6|${odl_ip[0]}|" "${pod_yaml}"
+    fi
+    if [[ ${gateway_ip[0]} ]]; then
+        sed -i "s|ip7|${gateway_ip[0]}|" "${pod_yaml}"
+    fi
 
     # update 'user' and 'key_filename' according to the CI env
     sed -i "s|node_username|${USER_NAME}|;s|node_keyfile|${SSH_KEY}|" "${pod_yaml}"
diff --git a/tests/opnfv/test_suites/opnfv_k8-nosdn-lb_ceph-noha_daily.yaml b/tests/opnfv/test_suites/opnfv_k8-nosdn-lb_ceph-noha_daily.yaml
new file mode 100644 (file)
index 0000000..ebb21b5
--- /dev/null
@@ -0,0 +1,18 @@
+##############################################################################
+# 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
+##############################################################################
+---
+# k8 nosdn lb ceph noha daily task suite
+
+schema: "yardstick:suite:0.1"
+
+name: "k8-nosdn-lb_ceph-noha"
+test_cases_dir: "tests/opnfv/test_cases/"
+test_cases:
+-
+  file_name: opnfv_yardstick_tc080.yaml
index faceeb6..bc48f99 100644 (file)
@@ -24,7 +24,7 @@ import unittest
 from tests.unit import STL_MOCKS
 from yardstick.common import utils
 from yardstick.network_services.vnf_generic.vnf.base import VnfdHelper
-
+from yardstick.network_services import constants
 
 STLClient = mock.MagicMock()
 stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
@@ -46,7 +46,6 @@ if stl_patch:
     from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxVpeProfileHelper
     from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxlwAFTRProfileHelper
 
-
 class TestCoreTuple(unittest.TestCase):
     def test___init__(self):
         core_tuple = CoreSocketTuple('core 5s6')
@@ -1537,7 +1536,9 @@ class TestProxDataHelper(unittest.TestCase):
         sut = mock.MagicMock()
         sut.port_stats.return_value = list(range(10))
 
-        data_helper = ProxDataHelper(vnfd_helper, sut, pkt_size, 25, None)
+        data_helper = ProxDataHelper(
+            vnfd_helper, sut, pkt_size, 25, None,
+            constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
 
         self.assertEqual(data_helper.rx_total, 6)
         self.assertEqual(data_helper.tx_total, 7)
@@ -1551,7 +1552,7 @@ class TestProxDataHelper(unittest.TestCase):
         sut = mock.MagicMock()
         sut.port_stats.return_value = list(range(10))
 
-        data_helper = ProxDataHelper(vnfd_helper, sut, None, None, None)
+        data_helper = ProxDataHelper(vnfd_helper, sut, None, None, None, None)
 
         expected = {
             'xe1': {
@@ -1574,13 +1575,15 @@ class TestProxDataHelper(unittest.TestCase):
         sut = mock.MagicMock()
         sut.port_stats.return_value = list(range(10))
 
-        data_helper = ProxDataHelper(vnfd_helper, sut, None, None, 5.4)
+        data_helper = ProxDataHelper(vnfd_helper, sut, None, None,
+            5.4, constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
         data_helper._totals_and_pps = 12, 32, 4.5
         data_helper.tsc_hz = 9.8
         data_helper.measured_stats = {'delta': TotStatsTuple(6.1, 6.2, 6.3, 6.4)}
         data_helper.latency = 7
 
         self.assertIsNone(data_helper.result_tuple)
+        self.assertEqual(data_helper.line_speed, 10000000000)
 
         expected = ProxTestDataTuple(5.4, 9.8, 6.1, 6.2, 6.3, 7, 12, 32, 4.5)
         with data_helper:
@@ -1595,7 +1598,7 @@ class TestProxDataHelper(unittest.TestCase):
     def test___enter___negative(self):
         vnfd_helper = mock.MagicMock()
 
-        data_helper = ProxDataHelper(vnfd_helper, None, None, None, None)
+        data_helper = ProxDataHelper(vnfd_helper, None, None, None, None, None)
 
         vnfd_helper.port_pairs.all_ports = []
         with self.assertRaises(AssertionError):
@@ -1617,7 +1620,7 @@ class TestProxDataHelper(unittest.TestCase):
         sut = ProxSocketHelper(mock.MagicMock())
         sut.get_all_tot_stats = mock.MagicMock(side_effect=[start, end])
 
-        data_helper = ProxDataHelper(vnfd_helper, sut, None, None, 5.4)
+        data_helper = ProxDataHelper(vnfd_helper, sut, None, None, 5.4, None)
 
         self.assertIsNone(data_helper.measured_stats)
 
@@ -1638,7 +1641,7 @@ class TestProxDataHelper(unittest.TestCase):
         sut = mock.MagicMock()
         sut.hz.return_value = '54.6'
 
-        data_helper = ProxDataHelper(vnfd_helper, sut, None, None, None)
+        data_helper = ProxDataHelper(vnfd_helper, sut, None, None, None, None)
 
         self.assertIsNone(data_helper.tsc_hz)
 
@@ -1935,7 +1938,8 @@ class TestProxProfileHelper(unittest.TestCase):
 
         helper = ProxProfileHelper(resource_helper)
 
-        helper.run_test(120, 5, 6.5)
+        helper.run_test(120, 5, 6.5,
+                        constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
 
 
 class TestProxMplsProfileHelper(unittest.TestCase):
@@ -2081,8 +2085,12 @@ class TestProxBngProfileHelper(unittest.TestCase):
 
         helper = ProxBngProfileHelper(resource_helper)
 
-        helper.run_test(120, 5, 6.5)
-        helper.run_test(-1000, 5, 6.5)  # negative pkt_size is the only way to make ratio > 1
+        helper.run_test(120, 5, 6.5,
+                        constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
+
+        # negative pkt_size is the only way to make ratio > 1
+        helper.run_test(-1000, 5, 6.5,
+                        constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
 
 
 class TestProxVpeProfileHelper(unittest.TestCase):
index 4407889..0d1dfb8 100644 (file)
@@ -134,16 +134,6 @@ class HeatContext(Context):
 
         self.attrs = attrs
 
-        self.key_filename = ''.join(
-            [consts.YARDSTICK_ROOT_PATH,
-             'yardstick/resources/files/yardstick_key-',
-              self.name])
-        # Permissions may have changed since creation; this can be fixed. If we
-        # overwrite the file, we lose future access to VMs using this key.
-        # As long as the file exists, even if it is unreadable, keep it intact
-        if not os.path.exists(self.key_filename):
-            SSH.gen_keys(self.key_filename)
-
     def check_environment(self):
         try:
             os.environ['OS_AUTH_URL']
@@ -185,6 +175,9 @@ class HeatContext(Context):
         template.add_security_group(self.secgroup_name)
 
         for network in self.networks.values():
+            # Using existing network
+            if network.is_existing():
+                continue
             template.add_network(network.stack_name,
                                  network.physical_network,
                                  network.provider,
@@ -308,7 +301,7 @@ class HeatContext(Context):
                                          timeout=self.heat_timeout)
          except KeyboardInterrupt:
              raise y_exc.StackCreationInterrupt
-         except:
+         except Exception:
              LOG.exception("stack failed")
              # let the other failures happen, we want stack trace
              raise
@@ -325,6 +318,16 @@ class HeatContext(Context):
         """deploys template into a stack using cloud"""
         LOG.info("Deploying context '%s' START", self.name)
 
+        self.key_filename = ''.join(
+            [consts.YARDSTICK_ROOT_PATH,
+             'yardstick/resources/files/yardstick_key-',
+             self.name])
+        # Permissions may have changed since creation; this can be fixed. If we
+        # overwrite the file, we lose future access to VMs using this key.
+        # As long as the file exists, even if it is unreadable, keep it intact
+        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)
 
@@ -354,18 +357,35 @@ class HeatContext(Context):
 
         LOG.info("Deploying context '%s' DONE", self.name)
 
+    @staticmethod
+    def _port_net_is_existing(port_info):
+        net_flags = port_info.get('net_flags', {})
+        return net_flags.get(consts.IS_EXISTING)
+
+    @staticmethod
+    def _port_net_is_public(port_info):
+        net_flags = port_info.get('net_flags', {})
+        return net_flags.get(consts.IS_PUBLIC)
+
     def add_server_port(self, server):
-        # use private ip from first port in first network
-        try:
-            private_port = next(iter(server.ports.values()))[0]
-        except IndexError:
-            LOG.exception("Unable to find first private port in %s", server.ports)
-            raise
-        server.private_ip = self.stack.outputs[private_port["stack_name"]]
+        server_ports = server.ports.values()
+        for server_port in server_ports:
+            port_info = server_port[0]
+            port_ip = self.stack.outputs[port_info["stack_name"]]
+            port_net_is_existing = self._port_net_is_existing(port_info)
+            port_net_is_public = self._port_net_is_public(port_info)
+            if port_net_is_existing and (port_net_is_public or
+                                         len(server_ports) == 1):
+                server.public_ip = port_ip
+            if not server.private_ip or len(server_ports) == 1:
+                server.private_ip = port_ip
+
         server.interfaces = {}
         for network_name, ports in server.ports.items():
             for port in ports:
                 # port['port'] is either port name from mapping or default network_name
+                if self._port_net_is_existing(port):
+                    continue
                 server.interfaces[port['port']] = self.make_interface_dict(network_name,
                                                                            port['port'],
                                                                            port['stack_name'],
index ae56066..a55c11f 100644 (file)
@@ -18,6 +18,8 @@ import logging
 from collections import Mapping
 from six.moves import range
 
+from yardstick.common import constants as consts
+
 
 LOG = logging.getLogger(__name__)
 
@@ -132,11 +134,28 @@ class Network(Object):
             if self.gateway_ip is None:
                 self.gateway_ip = "null"
 
-        if "external_network" in attrs:
-            self.router = Router("router", self.name,
-                                 context, attrs["external_network"])
-
-        Network.list.append(self)
+        self.net_flags = attrs.get('net_flags', {})
+        if self.is_existing():
+            self.subnet = attrs.get('subnet')
+            if not self.subnet:
+                raise Warning('No subnet set in existing netwrok!')
+        else:
+            if "external_network" in attrs:
+                self.router = Router("router", self.name,
+                                     context, attrs["external_network"])
+            Network.list.append(self)
+
+    def is_existing(self):
+        net_is_existing = self.net_flags.get(consts.IS_EXISTING)
+        if net_is_existing and not isinstance(net_is_existing, bool):
+            raise SyntaxError('Network flags should be bool type!')
+        return net_is_existing
+
+    def is_public(self):
+        net_is_public = self.net_flags.get(consts.IS_PUBLIC)
+        if net_is_public and not isinstance(net_is_public, bool):
+            raise SyntaxError('Network flags should be bool type!')
+        return net_is_public
 
     def has_route_to(self, network_name):
         """determines if this network has a route to the named network"""
@@ -302,10 +321,13 @@ class Server(Object):     # pragma: no cover
             # otherwise add a port for every network with port name as network name
             else:
                 ports = [network.name]
+            net_flags = network.net_flags
             for port in ports:
                 port_name = "{0}-{1}-port".format(server_name, port)
-                self.ports.setdefault(network.name, []).append(
-                    {"stack_name": port_name, "port": port})
+                port_info = {"stack_name": port_name, "port": port}
+                if net_flags:
+                    port_info['net_flags'] = net_flags
+                self.ports.setdefault(network.name, []).append(port_info)
                 # we can't use secgroups if port_security_enabled is False
                 if network.port_security_enabled is False:
                     sec_group_id = None
@@ -314,11 +336,14 @@ class Server(Object):     # pragma: no cover
                     sec_group_id = self.secgroup_name
                 # don't refactor to pass in network object, that causes JSON
                 # circular ref encode errors
-                template.add_port(port_name, network.stack_name, network.subnet_stack_name,
-                                  network.vnic_type, sec_group_id=sec_group_id,
+                template.add_port(port_name, network,
+                                  sec_group_id=sec_group_id,
                                   provider=network.provider,
                                   allowed_address_pairs=network.allowed_address_pairs)
-                port_name_list.append(port_name)
+                if network.is_public():
+                    port_name_list.insert(0, port_name)
+                else:
+                    port_name_list.append(port_name)
 
                 if self.floating_ip:
                     external_network = self.floating_ip["external_network"]
index 997a125..1996024 100644 (file)
@@ -45,7 +45,7 @@ class Report(object):
         self.task_id = ""
 
     def _validate(self, yaml_name, task_id):
-        if re.match("^[a-z0-9_-]+$", yaml_name):
+        if re.match(r"^[\w-]+$", yaml_name):
             self.yaml_name = yaml_name
         else:
             raise ValueError("invalid yaml_name", yaml_name)
@@ -102,10 +102,12 @@ class Report(object):
                     task_time = str(task_time, 'utf8')
                     key = str(key, 'utf8')
                 task_time = task_time[11:]
-                head, sep, tail = task_time.partition('.')
+                head, _, tail = task_time.partition('.')
                 task_time = head + "." + tail[:6]
                 self.Timestamp.append(task_time)
-                if isinstance(task[key], float) is True:
+                if task[key] is None:
+                    values.append('')
+                elif isinstance(task[key], (int, float)) is True:
                     values.append(task[key])
                 else:
                     values.append(ast.literal_eval(task[key]))
index 7f6309a..e7acde6 100644 (file)
@@ -149,7 +149,7 @@ class Task(object):     # pragma: no cover
                  total_end_time - total_start_time)
 
         LOG.info('To generate report, execute command "yardstick report '
-                 'generate %(task_id)s <yaml_name>s"', self.task_id)
+                 'generate %s <YAML_NAME>"', self.task_id)
         LOG.info("Task ALL DONE, exiting")
         return result
 
diff --git a/yardstick/benchmark/scenarios/availability/ha_tools/nova/add_server_to_existing_secgroup.bash b/yardstick/benchmark/scenarios/availability/ha_tools/nova/add_server_to_existing_secgroup.bash
new file mode 100644 (file)
index 0000000..3a50626
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+##############################################################################
+# 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
+##############################################################################
+
+# add server to existing security group
+# parameters: $1 - server name, $2 - security group name
+
+set -e
+
+if [ $OS_INSECURE ] && [ "$(echo $OS_INSECURE | tr '[:upper:]' '[:lower:]')" = "true" ]; then
+    SECURE="--insecure"
+else
+    SECURE=""
+fi
+
+SECGROUPNAME="$(openstack ${SECURE} security group list -f value -c Name | grep $2)"
+
+openstack ${SECURE} server add security group $1 ${SECGROUPNAME}
+
diff --git a/yardstick/benchmark/scenarios/availability/ha_tools/nova/get_server_privateip.bash b/yardstick/benchmark/scenarios/availability/ha_tools/nova/get_server_privateip.bash
new file mode 100644 (file)
index 0000000..7f2bad5
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+##############################################################################
+# 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
+##############################################################################
+
+# get private ip of a server
+# parameter: $1 - server name
+
+set -e
+
+if [ $OS_INSECURE ] && [ "$(echo $OS_INSECURE | tr '[:upper:]' '[:lower:]')" = "true" ]; then
+    SECURE="--insecure"
+else
+    SECURE=""
+fi
+
+openstack ${SECURE} server list -f value -c Name -c Networks | grep $1 | awk '{print $2}' | sed -r 's/.*=([0-9\.\:]+)[;,]*/\1/'
+
diff --git a/yardstick/benchmark/scenarios/availability/ha_tools/nova/remove_server_from_secgroup.bash b/yardstick/benchmark/scenarios/availability/ha_tools/nova/remove_server_from_secgroup.bash
new file mode 100644 (file)
index 0000000..61d0a2b
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+##############################################################################
+# 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
+##############################################################################
+
+# remove server from existing security group
+# parameters: $1 - server name, $2 - security group name
+
+set -e
+
+if [ $OS_INSECURE ] && [ "$(echo $OS_INSECURE | tr '[:upper:]' '[:lower:]')" = "true" ]; then
+    SECURE="--insecure"
+else
+    SECURE=""
+fi
+
+SECGROUPNAME="$(openstack ${SECURE} security group list -f value -c Name | grep $2)"
+
+openstack ${SECURE} server remove security group $1 ${SECGROUPNAME}
index dc51691..5f3f6c9 100644 (file)
@@ -35,3 +35,14 @@ get-vip-host:
   action_script: ha_tools/pacemaker/get_vip_host.bash
   rollback_script: ha_tools/pacemaker/get_resource_status.bash
 
+start-service:
+  action_script: ha_tools/start_service.bash
+  rollback_script: ha_tools/check_process_python.bash
+
+add-server-to-secgroup:
+  action_script: ha_tools/nova/add_server_to_existing_secgroup.bash
+  rollback_script: ha_tools/nova/remove_server_from_secgroup.bash
+
+get-privateip:
+  action_script: ha_tools/nova/get_server_privateip.bash
+  rollback_script: ha_tools/nova/list_servers.bash
diff --git a/yardstick/benchmark/scenarios/networking/moongen_testpmd.bash b/yardstick/benchmark/scenarios/networking/moongen_testpmd.bash
new file mode 100644 (file)
index 0000000..3e92cc9
--- /dev/null
@@ -0,0 +1,62 @@
+##############################################################################
+# Copyright (c) 2018 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
+##############################################################################
+#!/bin/bash
+
+set -e
+
+# Commandline arguments
+MOONGEN_PORT1_MAC=$1         # MAC address of the peer port
+MOONGEN_PORT2_MAC=$2         # MAC address of the peer port
+TESTPMD_QUEUE=$3
+
+BIND_ROOT='/opt/nsb_bin'
+DRIVER_ROOT='/opt/tempT/dpdk-17.02/'
+
+load_modules()
+{
+    if ! lsmod | grep "uio" &> /dev/null; then
+        modprobe uio
+    fi
+
+    if ! lsmod | grep "igb_uio" &> /dev/null; then
+        insmod ${DRIVER_ROOT}/x86_64-native-linuxapp-gcc/kmod/igb_uio.ko
+    fi
+
+    if ! lsmod | grep "rte_kni" &> /dev/null; then
+        insmod ${DRIVER_ROOT}/x86_64-native-linuxapp-gcc/kmod/rte_kni.ko
+    fi
+}
+
+change_permissions()
+{
+    chmod 777 /sys/bus/pci/drivers/virtio-pci/*
+    chmod 777 /sys/bus/pci/drivers/igb_uio/*
+}
+
+add_interface_to_dpdk(){
+    interfaces=$(lspci |grep Eth |tail -n +2 |awk '{print $1}')
+    ${BIND_ROOT}/dpdk_nic_bind.py --bind=igb_uio $interfaces &> /dev/null
+}
+
+run_testpmd()
+{
+    blacklist=$(lspci |grep Eth |awk '{print $1}'|head -1)
+    cd ${DRIVER_ROOT}
+    sudo ./x86_64-native-linuxapp-gcc/app/testpmd -c 0x3f -n 4 -b $blacklist -- -a --nb-cores=4 --coremask=0x3c --burst=64 --txd=4096 --rxd=4096 --rxq=$TESTPMD_QUEUE --txq=$TESTPMD_QUEUE  --rss-udp --eth-peer=0,$MOONGEN_PORT1_MAC --eth-peer=1,$MOONGEN_PORT2_MAC --forward-mode=mac
+}
+
+main()
+{
+    load_modules
+    change_permissions
+    add_interface_to_dpdk
+    run_testpmd
+}
+
+main
diff --git a/yardstick/benchmark/scenarios/networking/moongen_testpmd.py b/yardstick/benchmark/scenarios/networking/moongen_testpmd.py
new file mode 100644 (file)
index 0000000..86173c9
--- /dev/null
@@ -0,0 +1,378 @@
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd and others.
+#
+# 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.
+""" VsperfDPDK specific scenario definition """
+
+from __future__ import absolute_import
+import pkg_resources
+import logging
+import subprocess
+import time
+import re
+from oslo_serialization import jsonutils
+
+import yardstick.ssh as ssh
+import yardstick.common.utils as utils
+from yardstick.benchmark.scenarios import base
+
+LOG = logging.getLogger(__name__)
+
+
+class MoongenTestPMD(base.Scenario):
+    """Execute vsperf with defined parameters
+
+  Parameters:
+    frame_size - a frame size for which test should be executed;
+        Multiple frame sizes can be tested by modification of sequence runner
+        section inside TC YAML definition.
+        type:    string
+        default: "64"
+    multistream - the number of simulated streams
+        type:    string
+        default: 0 (disabled)
+    testpmd_queue - specifies how many queues you will use the VM
+                    only useful when forward_type is true.
+        type:    int
+        default: 1(one queue)
+    trafficgen_port1 - specifies device name of 1st interface connected to
+        the trafficgen
+        type:   string
+        default: NA
+    trafficgen_port2 - specifies device name of 2nd interface connected to
+        the trafficgen
+        type:   string
+        default: NA
+    moongen_host_user - specifies moongen host ssh user name
+        type: string
+        default: root
+    moongen_host_passwd - specifies moongen host ssh user password
+        type: string
+        default: root
+    moongen_host_ip - specifies moongen host ssh ip address
+        type: string
+        default NA
+    moongen_dir - specifies where is the moongen installtion dir
+        type: string
+        default NA
+    moongen_runBidirec - specifies moongen will run in one traffic
+                         or two traffic.
+        type: string
+        default true
+    Package_Loss - specifies the package_Loss number in moongen server.
+        type: int
+        default 0(0%)
+    SearchRuntime - specifies the SearchRuntime and validation time
+                    on moongen server.
+        type: int
+        default 60(s)
+    moongen_port1_mac - moongen server port1 mac address.
+        type: string
+        default NA
+    moongen_port2_mac - moongen server port2 mac address.
+        type: string
+        default NA
+    forward_type - VM forward type is l2fwd or testpmd.
+        type: string
+        default: testpmd
+    """
+    __scenario_type__ = "MoongenTestPMD"
+
+    TESTPMD_SCRIPT = 'moongen_testpmd.bash'
+    VSPERF_CONFIG = '/tmp/opnfv-vsperf-cfg.lua'
+
+    def __init__(self, scenario_cfg, context_cfg):
+        self.scenario_cfg = scenario_cfg
+        self.context_cfg = context_cfg
+        self.forward_setup_done = False
+        self.options = scenario_cfg.get('options', {})
+        self.moongen_host_user = \
+            self.options.get('moongen_host_user', "root")
+        self.moongen_host_passwd = \
+            self.options.get('moongen_host_passwd', "r00t")
+        self.moongen_dir = \
+            self.options.get('moongen_dir', '~/moongen.py')
+        self.testpmd_queue = \
+            self.options.get('testpmd_queue', 1)
+        self.moongen_host_ip = \
+            self.options.get('moongen_host_ip', "127.0.0.1")
+        self.moongen_port1_mac = \
+            self.options.get('moongen_port1_mac', None)
+        self.moongen_port2_mac = \
+            self.options.get('moongen_port2_mac', None)
+        self.tg_port1 = \
+            self.options.get('trafficgen_port1', "enp2s0f0")
+        self.tg_port2 = \
+            self.options.get('trafficgen_port2', "enp2s0f1")
+        self.forward_type = \
+            self.options.get('forward_type', 'testpmd')
+        self.tgen_port1_mac = None
+        self.tgen_port2_mac = None
+
+    def setup(self):
+        """scenario setup"""
+        host = self.context_cfg['host']
+
+        task_id = self.scenario_cfg['task_id']
+        context_number = task_id.split('-')[0]
+        self.tg_port1_nw = 'demo' + \
+            "-" + context_number + "-" + \
+            self.options.get('trafficgen_port1_nw', 'test2')
+        self.tg_port2_nw = 'demo' + \
+            "-" + context_number + "-" + \
+            self.options.get('trafficgen_port2_nw', 'test3')
+
+        # copy vsperf conf to VM
+        self.client = ssh.SSH.from_node(host, defaults={"user": "ubuntu"})
+        # traffic generation could last long
+        self.client.wait(timeout=1800)
+
+        self.server = ssh.SSH(
+            self.moongen_host_user,
+            self.moongen_host_ip,
+            password=self.moongen_host_passwd
+        )
+        # traffic generation could last long
+        self.server.wait(timeout=1800)
+
+        self.setup_done = True
+
+    def forward_setup(self):
+        """forward tool setup"""
+
+        # setup forward loopback in VM
+        self.testpmd_script = pkg_resources.resource_filename(
+            'yardstick.benchmark.scenarios.networking',
+            self.TESTPMD_SCRIPT)
+
+        self.client._put_file_shell(self.testpmd_script,
+                                    '~/testpmd_vsperf.sh')
+
+        # disable Address Space Layout Randomization (ASLR)
+        cmd = "echo 0 | sudo tee /proc/sys/kernel/randomize_va_space"
+        self.client.send_command(cmd)
+
+        if not self._is_forward_setup():
+            self.tgen_port1_ip = \
+                utils.get_port_ip(self.client, self.tg_port1)
+            self.tgen_port1_mac = \
+                utils.get_port_mac(self.client, self.tg_port1)
+            self.client.run("tee ~/.testpmd.ipaddr.port1 > /dev/null",
+                            stdin=self.tgen_port1_ip)
+            self.client.run("tee ~/.testpmd.macaddr.port1 > /dev/null",
+                            stdin=self.tgen_port1_mac)
+            self.tgen_port2_ip = \
+                utils.get_port_ip(self.client, self.tg_port2)
+            self.tgen_port2_mac = \
+                utils.get_port_mac(self.client, self.tg_port2)
+            self.client.run("tee ~/.testpmd.ipaddr.port2 > /dev/null",
+                            stdin=self.tgen_port2_ip)
+            self.client.run("tee ~/.testpmd.macaddr.port2 > /dev/null",
+                            stdin=self.tgen_port2_mac)
+        else:
+            cmd = "cat ~/.testpmd.macaddr.port1"
+            status, stdout, stderr = self.client.execute(cmd)
+            if status:
+                raise RuntimeError(stderr)
+            self.tgen_port1_mac = stdout
+            cmd = "cat ~/.testpmd.ipaddr.port1"
+            status, stdout, stderr = self.client.execute(cmd)
+            if status:
+                raise RuntimeError(stderr)
+            self.tgen_port1_ip = stdout
+            cmd = "cat ~/.testpmd.macaddr.port2"
+            status, stdout, stderr = self.client.execute(cmd)
+            if status:
+                raise RuntimeError(stderr)
+            self.tgen_port2_mac = stdout
+            cmd = "cat ~/.testpmd.ipaddr.port2"
+            status, stdout, stderr = self.client.execute(cmd)
+            if status:
+                raise RuntimeError(stderr)
+            self.tgen_port2_ip = stdout
+
+        LOG.info("forward type is %s", self.forward_type)
+        if self.forward_type == 'testpmd':
+            cmd = "sudo ip link set %s down" % (self.tg_port1)
+            LOG.debug("Executing command: %s", cmd)
+            self.client.execute(cmd)
+            cmd = "sudo ip link set %s down" % (self.tg_port2)
+            LOG.debug("Executing command: %s", cmd)
+            self.client.execute(cmd)
+            cmd = "screen -d -m sudo -E bash ~/testpmd_vsperf.sh %s %s %d" % \
+                (self.moongen_port1_mac, self.moongen_port2_mac,
+                 self.testpmd_queue)
+            LOG.debug("Executing command: %s", cmd)
+            status, stdout, stderr = self.client.execute(cmd)
+            if status:
+                raise RuntimeError(stderr)
+
+        elif self.forward_type == 'l2fwd':
+            cmd = ('sed -i "s/static char *net1 = \\\"eth1\\\";'
+                   '/static char *net1 = \\\"%s %s %s\\\";/g" /home/l2fwd/l2fwd.c'
+                   % (self.tg_port1, self.tgen_port1_ip, self.moongen_port1_mac))
+            LOG.debug("Executing command: %s", cmd)
+            status, stdout, stderr = self.client.execute(cmd)
+
+            cmd = ('sed -i "s/static char *net2 = \\\"eth2\\\";'
+                   '/static char *net2 = \\\"%s %s %s\\\";/g" /home/l2fwd/l2fwd.c'
+                   % (self.tg_port2, self.tgen_port2_ip, self.moongen_port2_mac))
+            LOG.debug("Executing command: %s", cmd)
+            status, stdout, stderr = self.client.execute(cmd)
+
+            cmd = ('cd /home/l2fwd/;make;./gen_debian_package.sh;'
+                   'sudo dpkg -i *.deb;'
+                   'sudo modprobe l2fwd')
+            LOG.debug("Executing command: %s", cmd)
+            status, stdout, stderr = self.client.execute(cmd)
+
+        time.sleep(1)
+
+        self.forward_setup_done = True
+
+    def _is_forward_setup(self):
+        """Is forward already setup in the host?"""
+        if self.forward_type is 'testpmd':
+            is_run = True
+            cmd = "ip a | grep %s 2>/dev/null" % (self.tg_port1)
+            LOG.debug("Executing command: %s", cmd)
+            _, stdout, _ = self.client.execute(cmd)
+            if stdout:
+                is_run = False
+            return is_run
+        elif self.forward_type is 'l2fwd':
+            cmd = ('sudo lsmod |grep l2fwd')
+            LOG.debug("Executing command: %s", cmd)
+            _, stdout, _ = self.client.execute(cmd)
+            if stdout:
+                return True
+            else:
+                return False
+
+    def generate_config_file(self, frame_size, multistream,
+                             runBidirec, tg_port1_vlan, tg_port2_vlan,
+                             SearchRuntime, Package_Loss):
+        out_text = """\
+VSPERF {
+testType = 'throughput',
+nrFlows = %d,
+runBidirec = %s,
+frameSize = %d,
+srcMacs = {\'%s\', \'%s\'},
+dstMacs = {\'%s\', \'%s\'},
+vlanIds = {%d, %d},
+searchRunTime = %d,
+validationRunTime = %d,
+acceptableLossPct = %d,
+ports = {0,1},
+}
+""" % (multistream, runBidirec, frame_size, self.moongen_port1_mac,
+       self.moongen_port2_mac, self.tgen_port1_mac, self.tgen_port2_mac,
+       tg_port1_vlan, tg_port2_vlan, SearchRuntime, SearchRuntime, Package_Loss)
+        with open(self.VSPERF_CONFIG, "wt") as out_file:
+           out_file.write(out_text)
+        self.CONFIG_FILE = True
+
+    def result_to_data(self, result):
+        search_pattern = re.compile(
+            r'\[REPORT\]\s+total\:\s+'
+            r'Tx\s+frames\:\s+(\d+)\s+'
+            r'Rx\s+Frames\:\s+(\d+)\s+'
+            r'frame\s+loss\:\s+(\d+)\,'
+            r'\s+(\d+\.\d+|\d+)%\s+'
+            r'Tx\s+Mpps\:\s+(\d+.\d+|\d+)\s+'
+            r'Rx\s+Mpps\:\s+(\d+\.\d+|\d+)',
+            re.IGNORECASE)
+        results_match = search_pattern.search(result)
+        if results_match:
+            rx_mpps = float(results_match.group(6))
+            tx_mpps = float(results_match.group(5))
+        else:
+            rx_mpps = 0
+            tx_mpps = 0
+        test_result = {"rx_mpps": rx_mpps, "tx_mpps": tx_mpps}
+        self.TO_DATA = True
+        return test_result
+
+    def run(self, result):
+        """ execute the vsperf benchmark and return test results
+            within result dictionary
+        """
+
+        if not self.setup_done:
+            self.setup()
+
+        # get vsperf options
+        multistream = self.options.get("multistream", 1)
+
+        if not self.forward_setup_done:
+            self.forward_setup()
+
+        if 'frame_size' in self.options:
+            frame_size = self.options.get("frame_size", 64)
+        Package_Loss = self.options.get("Package_Loss", 0)
+        runBidirec = self.options.get("moongen_runBidirec",
+                                                      "true")
+        SearchRuntime = self.options.get("SearchRuntime", 10)
+
+        cmd = "openstack network show %s --format json -c " \
+              "provider:segmentation_id" % (self.tg_port1_nw)
+        LOG.debug("Executing command: %s", cmd)
+        output = subprocess.check_output(cmd, shell=True)
+        try:
+            tg_port1_vlan = jsonutils.loads(output).get("provider:segmentation_id", 1)
+        except TypeError:
+            tg_port1_vlan = 1
+
+        cmd = "openstack network show %s --format json -c " \
+              "provider:segmentation_id" % (self.tg_port2_nw)
+        LOG.debug("Executing command: %s", cmd)
+        output = subprocess.check_output(cmd, shell=True)
+        try:
+            tg_port2_vlan = jsonutils.loads(output).get("provider:segmentation_id", 2)
+        except TypeError:
+            tg_port2_vlan = 2
+
+        self.generate_config_file(frame_size, multistream,
+                                  runBidirec, tg_port1_vlan,
+                                  tg_port2_vlan, SearchRuntime, Package_Loss)
+
+        self.server.execute("rm -f -- %s/opnfv-vsperf-cfg.lua" %
+                            (self.moongen_dir))
+        self.server._put_file_shell(self.VSPERF_CONFIG,
+                                    "%s/opnfv-vsperf-cfg.lua"
+                                    % (self.moongen_dir))
+
+        # execute moongen
+        cmd = ("cd %s;./MoonGen/build/MoonGen ./trafficgen.lua"
+               % (self.moongen_dir))
+        status, stdout, stderr = self.server.execute(cmd)
+        if status:
+            raise RuntimeError(stderr)
+
+        moongen_result = self.result_to_data(stdout)
+        LOG.info(moongen_result)
+        result.update(moongen_result)
+
+        if "sla" in self.scenario_cfg:
+            throughput_rx_mpps = int(
+                self.scenario_cfg["sla"]["throughput_rx_mpps"])
+
+            assert throughput_rx_mpps <= moongen_result["tx_mpps"], \
+                "sla_throughput_rx_mpps %f > throughput_rx_mpps(%f); " % \
+                (throughput_rx_mpps, moongen_result["tx_mpps"])
+
+    def teardown(self):
+        """cleanup after the test execution"""
+
+        # execute external setup script
+        self.setup_done = False
index 125bc7e..d3ed840 100644 (file)
@@ -124,12 +124,16 @@ class Fio(base.Scenario):
 
         if mount_dir:
             LOG.debug("Formating volume...")
-            self.client.execute("sudo mkfs.ext4 /dev/vdb")
-            cmd = "sudo mkdir %s" % mount_dir
-            self.client.execute(cmd)
-            LOG.debug("Mounting volume at: %s", mount_dir)
-            cmd = "sudo mount /dev/vdb %s" % mount_dir
-            self.client.execute(cmd)
+            _, stdout, _ = self.client.execute(
+                "lsblk -dps | grep -m 1 disk | awk '{print $1}'")
+            block_device = stdout.strip()
+            if block_device:
+                 self.client.execute("sudo mkfs.ext4 %s" % block_device)
+                 cmd = "sudo mkdir %s" % mount_dir
+                 self.client.execute(cmd)
+                 LOG.debug("Mounting volume at: %s", mount_dir)
+                 cmd = "sudo mount %s %s" % (block_device, mount_dir)
+                 self.client.execute(cmd)
 
         self.setup_done = True
 
index 43c2c19..153bd4b 100644 (file)
@@ -145,6 +145,10 @@ BASE_URL = 'http://localhost:5000'
 ENV_ACTION_API = BASE_URL + '/yardstick/env/action'
 ASYNC_TASK_API = BASE_URL + '/yardstick/asynctask'
 
+# flags
+IS_EXISTING = 'is_existing'
+IS_PUBLIC = 'is_public'
+
 # general
 TESTCASE_PRE = 'opnfv_yardstick_'
 TESTSUITE_PRE = 'opnfv_'
index 9946bf1..7f72887 100644 (file)
@@ -67,7 +67,7 @@ class YardstickBannedModuleImported(YardstickException):
 class HeatTemplateError(YardstickException):
     """Error in Heat during the stack deployment"""
     message = ('Error in Heat during the creation of the OpenStack stack '
-               '"%(stack_name)"')
+               '"%(stack_name)s"')
 
 
 class IPv6RangeError(YardstickException):
index 79951e3..0064b4f 100644 (file)
@@ -15,3 +15,5 @@
 REMOTE_TMP = "/tmp"
 DEFAULT_VNF_TIMEOUT = 3600
 PROCESS_JOIN_TIMEOUT = 3
+ONE_GIGABIT_IN_BITS = 1000000000
+NIC_GBPS_DEFAULT = 10
index 5700f98..c3277fb 100644 (file)
@@ -20,6 +20,7 @@ import datetime
 import time
 
 from yardstick.network_services.traffic_profile.prox_profile import ProxProfile
+from yardstick.network_services import constants
 
 LOG = logging.getLogger(__name__)
 
@@ -99,9 +100,13 @@ class ProxBinSearchProfile(ProxProfile):
 
         # throughput and packet loss from the most recent successful test
         successful_pkt_loss = 0.0
+        line_speed = traffic_gen.scenario_helper.all_options.get(
+            "interface_speed_gbps", constants.NIC_GBPS_DEFAULT) * constants.ONE_GIGABIT_IN_BITS
         for test_value in self.bounds_iterator(LOG):
             result, port_samples = self._profile_helper.run_test(pkt_size, duration,
-                                                                 test_value, self.tolerated_loss)
+                                                                 test_value,
+                                                                 self.tolerated_loss,
+                                                                 line_speed)
             self.curr_time = time.time()
             diff_time = self.curr_time - self.prev_time
             self.prev_time = self.curr_time
index 29f9c7b..e42431f 100644 (file)
@@ -35,6 +35,7 @@ from yardstick.common.utils import SocketTopology, join_non_strings, try_int
 from yardstick.network_services.helpers.iniparser import ConfigParser
 from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper
 from yardstick.network_services.vnf_generic.vnf.sample_vnf import DpdkVnfSetupEnvHelper
+from yardstick.network_services import constants
 
 PROX_PORT = 8474
 
@@ -44,7 +45,6 @@ SECTION_CONTENTS = 1
 LOG = logging.getLogger(__name__)
 LOG.setLevel(logging.DEBUG)
 
-TEN_GIGABIT = 1e10
 BITS_PER_BYTE = 8
 RETRY_SECONDS = 60
 RETRY_INTERVAL = 1
@@ -466,13 +466,14 @@ class ProxSocketHelper(object):
                 core_data['current'] = core_data[key1] + core_data[key2]
                 self.set_speed(core_data['cores'], core_data['current'])
 
-    def set_pps(self, cores, pps, pkt_size):
+    def set_pps(self, cores, pps, pkt_size,
+                line_speed=(constants.ONE_GIGABIT_IN_BITS * constants.NIC_GBPS_DEFAULT)):
         """ set packets per second for specific cores on the remote instance """
         msg = "Set packets per sec for core(s) %s to %g%% of line rate (packet size: %d)"
         LOG.debug(msg, cores, pps, pkt_size)
 
         # speed in percent of line-rate
-        speed = float(pps) * (pkt_size + 20) / TEN_GIGABIT / BITS_PER_BYTE
+        speed = float(pps) * (pkt_size + 20) / line_speed / BITS_PER_BYTE
         self._run_template_over_cores("speed {} 0 {}\n", cores, speed)
 
     def lat_stats(self, cores, task=0):
@@ -967,12 +968,13 @@ class ProxResourceHelper(ClientResourceHelper):
 
 class ProxDataHelper(object):
 
-    def __init__(self, vnfd_helper, sut, pkt_size, value, tolerated_loss):
+    def __init__(self, vnfd_helper, sut, pkt_size, value, tolerated_loss, line_speed):
         super(ProxDataHelper, self).__init__()
         self.vnfd_helper = vnfd_helper
         self.sut = sut
         self.pkt_size = pkt_size
         self.value = value
+        self.line_speed = line_speed
         self.tolerated_loss = tolerated_loss
         self.port_count = len(self.vnfd_helper.port_pairs.all_ports)
         self.tsc_hz = None
@@ -1058,9 +1060,7 @@ class ProxDataHelper(object):
         self.tsc_hz = float(self.sut.hz())
 
     def line_rate_to_pps(self):
-        # NOTE: to fix, don't hardcode 10Gb/s
-        return self.port_count * TEN_GIGABIT / BITS_PER_BYTE / (self.pkt_size + 20)
-
+      return self.port_count * self.line_speed  / BITS_PER_BYTE / (self.pkt_size + 20)
 
 class ProxProfileHelper(object):
 
@@ -1139,8 +1139,10 @@ class ProxProfileHelper(object):
 
         return cores
 
-    def run_test(self, pkt_size, duration, value, tolerated_loss=0.0):
-        data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size, value, tolerated_loss)
+    def run_test(self, pkt_size, duration, value, tolerated_loss=0.0,
+                 line_speed=(constants.ONE_GIGABIT_IN_BITS * constants.NIC_GBPS_DEFAULT)):
+        data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size,
+                                     value, tolerated_loss, line_speed)
 
         with data_helper, self.traffic_context(pkt_size, value):
             with data_helper.measure_tot_stats():
@@ -1396,8 +1398,10 @@ class ProxBngProfileHelper(ProxProfileHelper):
         time.sleep(3)
         self.sut.stop(self.all_rx_cores)
 
-    def run_test(self, pkt_size, duration, value, tolerated_loss=0.0):
-        data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size, value, tolerated_loss)
+    def run_test(self, pkt_size, duration, value, tolerated_loss=0.0,
+                 line_speed=(constants.ONE_GIGABIT_IN_BITS * constants.NIC_GBPS_DEFAULT)):
+        data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size,
+                                     value, tolerated_loss, line_speed)
 
         with data_helper, self.traffic_context(pkt_size, value):
             with data_helper.measure_tot_stats():
@@ -1583,8 +1587,10 @@ class ProxVpeProfileHelper(ProxProfileHelper):
         time.sleep(3)
         self.sut.stop(self.all_rx_cores)
 
-    def run_test(self, pkt_size, duration, value, tolerated_loss=0.0):
-        data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size, value, tolerated_loss)
+    def run_test(self, pkt_size, duration, value, tolerated_loss=0.0,
+                 line_speed=(constants.ONE_GIGABIT_IN_BITS * constants.NIC_GBPS_DEFAULT)):
+        data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size,
+                                     value, tolerated_loss, line_speed)
 
         with data_helper, self.traffic_context(pkt_size, value):
             with data_helper.measure_tot_stats():
@@ -1772,8 +1778,10 @@ class ProxlwAFTRProfileHelper(ProxProfileHelper):
         time.sleep(3)
         self.sut.stop(self.all_rx_cores)
 
-    def run_test(self, pkt_size, duration, value, tolerated_loss=0.0):
-        data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size, value, tolerated_loss)
+    def run_test(self, pkt_size, duration, value, tolerated_loss=0.0,
+                 line_speed=(constants.ONE_GIGABIT_IN_BITS * constants.NIC_GBPS_DEFAULT)):
+        data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size,
+                                     value, tolerated_loss, line_speed)
 
         with data_helper, self.traffic_context(pkt_size, value):
             with data_helper.measure_tot_stats():
index 2cdb3f9..285e086 100644 (file)
@@ -22,7 +22,7 @@ from yardstick.common.process import check_if_process_failed
 from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxDpdkVnfSetupEnvHelper
 from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxResourceHelper
 from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNF
-from yardstick.network_services.constants import PROCESS_JOIN_TIMEOUT
+from yardstick.network_services import constants
 
 LOG = logging.getLogger(__name__)
 
@@ -136,5 +136,5 @@ class ProxApproxVnf(SampleVNF):
         self._tear_down()
         if self._vnf_process is not None:
             LOG.debug("joining before terminate %s", self._vnf_process.name)
-            self._vnf_process.join(PROCESS_JOIN_TIMEOUT)
+            self._vnf_process.join(constants.PROCESS_JOIN_TIMEOUT)
             self._vnf_process.terminate()
index f16b414..c19a8d4 100644 (file)
@@ -32,9 +32,7 @@ from yardstick.benchmark.contexts.base import Context
 from yardstick.common import exceptions as y_exceptions
 from yardstick.common.process import check_if_process_failed
 from yardstick.common import utils
-from yardstick.network_services.constants import DEFAULT_VNF_TIMEOUT
-from yardstick.network_services.constants import PROCESS_JOIN_TIMEOUT
-from yardstick.network_services.constants import REMOTE_TMP
+from yardstick.network_services import constants
 from yardstick.network_services.helpers.dpdkbindnic_helper import DpdkBindHelper, DpdkNode
 from yardstick.network_services.helpers.samplevnf_helper import MultiPortConfig
 from yardstick.network_services.helpers.samplevnf_helper import PortPairs
@@ -51,8 +49,8 @@ LOG = logging.getLogger(__name__)
 
 class SetupEnvHelper(object):
 
-    CFG_CONFIG = os.path.join(REMOTE_TMP, "sample_config")
-    CFG_SCRIPT = os.path.join(REMOTE_TMP, "sample_script")
+    CFG_CONFIG = os.path.join(constants.REMOTE_TMP, "sample_config")
+    CFG_SCRIPT = os.path.join(constants.REMOTE_TMP, "sample_script")
     DEFAULT_CONFIG_TPL_CFG = "sample.cfg"
     PIPELINE_COMMAND = ''
     VNF_TYPE = "SAMPLE"
@@ -609,8 +607,10 @@ class ScenarioHelper(object):
 
     @property
     def timeout(self):
-        return self.options.get('timeout', DEFAULT_VNF_TIMEOUT)
-
+        test_duration = self.scenario_cfg.get('runner', {}).get('duration',
+            self.options.get('timeout', constants.DEFAULT_VNF_TIMEOUT))
+        test_timeout = self.options.get('timeout', constants.DEFAULT_VNF_TIMEOUT)
+        return test_duration if test_duration > test_timeout else test_timeout
 
 class SampleVNF(GenericVNF):
     """ Class providing file-like API for generic VNF implementation """
@@ -794,7 +794,7 @@ class SampleVNF(GenericVNF):
         if self._vnf_process is not None:
             # be proper and join first before we kill
             LOG.debug("joining before terminate %s", self._vnf_process.name)
-            self._vnf_process.join(PROCESS_JOIN_TIMEOUT)
+            self._vnf_process.join(constants.PROCESS_JOIN_TIMEOUT)
             self._vnf_process.terminate()
         # no terminate children here because we share processes with tg
 
@@ -938,12 +938,12 @@ class SampleVNFTrafficGen(GenericTrafficGen):
         if self._traffic_process is not None:
             # be proper and try to join before terminating
             LOG.debug("joining before terminate %s", self._traffic_process.name)
-            self._traffic_process.join(PROCESS_JOIN_TIMEOUT)
+            self._traffic_process.join(constants.PROCESS_JOIN_TIMEOUT)
             self._traffic_process.terminate()
         if self._tg_process is not None:
             # be proper and try to join before terminating
             LOG.debug("joining before terminate %s", self._tg_process.name)
-            self._tg_process.join(PROCESS_JOIN_TIMEOUT)
+            self._tg_process.join(constants.PROCESS_JOIN_TIMEOUT)
             self._tg_process.terminate()
         # no terminate children here because we share processes with vnf
 
index 8e02cf3..de6fd93 100644 (file)
@@ -17,7 +17,7 @@ import os
 
 from six.moves import StringIO
 
-from yardstick.network_services.constants import REMOTE_TMP
+from yardstick.network_services import constants
 from yardstick.ssh import AutoConnectSSH
 
 LOG = logging.getLogger(__name__)
@@ -46,7 +46,7 @@ class VnfSshHelper(AutoConnectSSH):
         return self.get_class()(self.node, self.bin_path)
 
     def upload_config_file(self, prefix, content):
-        cfg_file = os.path.join(REMOTE_TMP, prefix)
+        cfg_file = os.path.join(constants.REMOTE_TMP, prefix)
         LOG.debug(content)
         file_obj = StringIO(content)
         self.put_file_obj(file_obj, cfg_file)
index 20be89f..d69f860 100644 (file)
@@ -26,6 +26,7 @@ import shade
 import yardstick.common.openstack_utils as op_utils
 from yardstick.common import exceptions
 from yardstick.common import template_format
+from yardstick.common import constants as consts
 
 log = logging.getLogger(__name__)
 
@@ -333,21 +334,24 @@ name (i.e. %s).
             }
         }
 
-    def add_port(self, name, network_name, subnet_name, vnic_type, sec_group_id=None,
+    def add_port(self, name, network, sec_group_id=None,
                  provider=None, allowed_address_pairs=None):
         """add to the template a named Neutron Port
         """
-        log.debug("adding Neutron::Port '%s', network:'%s', subnet:'%s', vnic_type:'%s', "
-                  "secgroup:%s", name, network_name, subnet_name, vnic_type, sec_group_id)
+        net_is_existing = network.net_flags.get(consts.IS_EXISTING)
+        depends_on = [] if net_is_existing else [network.subnet_stack_name]
+        fixed_ips = [{'subnet': network.subnet}] if net_is_existing else [
+            {'subnet': {'get_resource': network.subnet_stack_name}}]
+        network_ = network.name if net_is_existing else {
+            'get_resource': network.stack_name}
         self.resources[name] = {
             'type': 'OS::Neutron::Port',
-            'depends_on': [subnet_name],
+            'depends_on': depends_on,
             'properties': {
                 'name': name,
-                'binding:vnic_type': vnic_type,
-                'fixed_ips': [{'subnet': {'get_resource': subnet_name}}],
-                'network_id': {'get_resource': network_name},
-                'replacement_policy': 'AUTO',
+                'binding:vnic_type': network.vnic_type,
+                'fixed_ips': fixed_ips,
+                'network': network_,
             }
         }
 
@@ -364,6 +368,8 @@ name (i.e. %s).
             self.resources[name]['properties'][
                 'allowed_address_pairs'] = allowed_address_pairs
 
+        log.debug("adding Neutron::Port %s", self.resources[name])
+
         self._template['outputs'][name] = {
             'description': 'Address for interface %s' % name,
             'value': {'get_attr': [name, 'fixed_ips', 0, 'ip_address']}
index 479db8a..625f97b 100644 (file)
 from collections import OrderedDict
 from itertools import count
 import logging
+import os
 
 import mock
 import unittest
 
-import shade
-
 from yardstick.benchmark.contexts import base
 from yardstick.benchmark.contexts import heat
 from yardstick.benchmark.contexts import model
+from yardstick.common import constants as consts
 from yardstick.common import exceptions as y_exc
-from yardstick.orchestrator import heat as orch_heat
 from yardstick import ssh
 
 
@@ -62,12 +61,11 @@ class HeatContextTestCase(unittest.TestCase):
         self.assertIsNone(self.test_context.heat_parameters)
         self.assertIsNone(self.test_context.key_filename)
 
-    @mock.patch.object(ssh.SSH, 'gen_keys')
     @mock.patch('yardstick.benchmark.contexts.heat.PlacementGroup')
     @mock.patch('yardstick.benchmark.contexts.heat.ServerGroup')
     @mock.patch('yardstick.benchmark.contexts.heat.Network')
     @mock.patch('yardstick.benchmark.contexts.heat.Server')
-    def test_init(self, mock_server, mock_network, mock_sg, mock_pg, mock_ssh_gen_keys):
+    def test_init(self, mock_server, mock_network, mock_sg, mock_pg):
 
         pgs = {'pgrp1': {'policy': 'availability'}}
         sgs = {'servergroup1': {'policy': 'affinity'}}
@@ -105,8 +103,6 @@ class HeatContextTestCase(unittest.TestCase):
                                        servers['baz'])
         self.assertEqual(len(self.test_context.servers), 1)
 
-        mock_ssh_gen_keys.assert_called()
-
     def test_init_no_name_or_task_id(self):
         attrs = {}
         self.assertRaises(KeyError, self.test_context.init, attrs)
@@ -128,8 +124,7 @@ class HeatContextTestCase(unittest.TestCase):
         self.assertEqual(self.test_context.name, 'foo')
         self.assertEqual(self.test_context.assigned_name, 'foo')
 
-    @mock.patch('yardstick.ssh.SSH.gen_keys')
-    def test_init_no_setup_no_teardown(self, *args):
+    def test_init_no_setup_no_teardown(self):
 
         attrs = {'name': 'foo',
                  'task_id': '1234567890',
@@ -222,9 +217,11 @@ class HeatContextTestCase(unittest.TestCase):
                           self.test_context._create_new_stack,
                           template)
 
-    @mock.patch.object(orch_heat.HeatTemplate, 'add_keypair')
+    @mock.patch.object(os.path, 'exists', return_value=True)
+    @mock.patch.object(heat.HeatContext, '_add_resources_to_template')
     @mock.patch.object(heat.HeatContext, '_create_new_stack')
-    def test_deploy_stack_creation_failed(self, mock_create, *args):
+    def test_deploy_stack_creation_failed(self, mock_create,
+            mock_resources_template, mock_path_exists):
         self.test_context._name = 'foo'
         self.test_context._task_id = '1234567890'
         self.test_context._name_task_id = 'foo-12345678'
@@ -232,8 +229,13 @@ class HeatContextTestCase(unittest.TestCase):
         self.assertRaises(y_exc.HeatTemplateError,
                           self.test_context.deploy)
 
+        mock_path_exists.assert_called_once()
+        mock_resources_template.assert_called_once()
+
+    @mock.patch.object(os.path, 'exists', return_value=False)
+    @mock.patch.object(ssh.SSH, 'gen_keys')
     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
-    def test_deploy(self, mock_template):
+    def test_deploy(self, mock_template, mock_genkeys, mock_path_exists):
         self.test_context._name = 'foo'
         self.test_context._task_id = '1234567890'
         self.test_context._name_task_id = '{}-{}'.format(
@@ -247,46 +249,98 @@ class HeatContextTestCase(unittest.TestCase):
                                          '/bar/baz/some-heat-file',
                                          {'image': 'cirros'})
         self.assertIsNotNone(self.test_context.stack)
+        key_filename = ''.join(
+            [consts.YARDSTICK_ROOT_PATH,
+             'yardstick/resources/files/yardstick_key-',
+             self.test_context._name_task_id])
+        mock_genkeys.assert_called_once_with(key_filename)
+        mock_path_exists.assert_called_once_with(key_filename)
 
-    # TODO: patch objects
     @mock.patch.object(heat, 'HeatTemplate')
+    @mock.patch.object(os.path, 'exists', return_value=False)
+    @mock.patch.object(ssh.SSH, 'gen_keys')
     @mock.patch.object(heat.HeatContext, '_retrieve_existing_stack')
     @mock.patch.object(heat.HeatContext, '_create_new_stack')
-    def test_deploy_no_setup(self, mock_create_new_stack, mock_retrieve_existing_stack, *args):
+    def test_deploy_no_setup(self, mock_create_new_stack,
+            mock_retrieve_existing_stack, mock_genkeys, mock_path_exists,
+            *args):
         self.test_context._name = 'foo'
         self.test_context._task_id = '1234567890'
-        # Might be able to get rid of these
         self.test_context.template_file = '/bar/baz/some-heat-file'
         self.test_context.heat_parameters = {'image': 'cirros'}
         self.test_context.get_neutron_info = mock.MagicMock()
         self.test_context._flags.no_setup = True
         self.test_context.deploy()
 
-        # check that heat client is called...
         mock_create_new_stack.assert_not_called()
         mock_retrieve_existing_stack.assert_called_with(self.test_context.name)
         self.assertIsNotNone(self.test_context.stack)
+        key_filename = ''.join(
+            [consts.YARDSTICK_ROOT_PATH,
+             'yardstick/resources/files/yardstick_key-',
+             self.test_context._name])
+        mock_genkeys.assert_called_once_with(key_filename)
+        mock_path_exists.assert_called_once_with(key_filename)
 
-    @mock.patch.object(shade, 'openstack_cloud')
-    @mock.patch.object(heat.HeatTemplate, 'add_keypair')
+    @mock.patch.object(heat, 'HeatTemplate')
+    @mock.patch.object(os.path, 'exists', return_value=False)
+    @mock.patch.object(ssh.SSH, 'gen_keys')
     @mock.patch.object(heat.HeatContext, '_create_new_stack')
-    @mock.patch.object(heat.HeatStack, 'get')
+    @mock.patch.object(heat.HeatContext, '_retrieve_existing_stack',
+                       return_value=None)
     def test_deploy_try_retrieve_context_does_not_exist(self,
-                                                        mock_get_stack,
-                                                        mock_create_new_stack,
-                                                        *args):
+            mock_retrieve_stack, mock_create_new_stack, mock_genkeys,
+            mock_path_exists, *args):
         self.test_context._name = 'demo'
         self.test_context._task_id = '1234567890'
         self.test_context._flags.no_setup = True
+        self.test_context.template_file = '/bar/baz/some-heat-file'
         self.test_context.get_neutron_info = mock.MagicMock()
 
-        # TODo: Check is this the right value to return, should it be None instead?
-        mock_get_stack.return_value = []
-
         self.test_context.deploy()
 
-        mock_get_stack.assert_called()
+        mock_retrieve_stack.assert_called_once_with(self.test_context._name)
         mock_create_new_stack.assert_called()
+        key_filename = ''.join(
+            [consts.YARDSTICK_ROOT_PATH,
+             'yardstick/resources/files/yardstick_key-',
+             self.test_context._name])
+        mock_genkeys.assert_called_once_with(key_filename)
+        mock_path_exists.assert_called_once_with(key_filename)
+
+    @mock.patch.object(heat, 'HeatTemplate', return_value='heat_template')
+    @mock.patch.object(heat.HeatContext, '_add_resources_to_template')
+    @mock.patch.object(os.path, 'exists', return_value=False)
+    @mock.patch.object(ssh.SSH, 'gen_keys')
+    def test_deploy_ssh_key_before_adding_resources(self, mock_genkeys,
+            mock_path_exists, mock_add_resources, *args):
+        mock_manager = mock.Mock()
+        mock_manager.attach_mock(mock_add_resources,
+                                 '_add_resources_to_template')
+        mock_manager.attach_mock(mock_genkeys, 'gen_keys')
+        mock_manager.reset_mock()
+        self.test_context._name_task_id = 'demo-12345678'
+        self.test_context.get_neutron_info = mock.Mock()
+        with mock.patch.object(self.test_context, '_create_new_stack') as \
+                mock_create_stack, \
+                mock.patch.object(self.test_context, 'get_neutron_info') as \
+                mock_neutron_info:
+            self.test_context.deploy()
+
+        mock_neutron_info.assert_called_once()
+        mock_create_stack.assert_called_once()
+        key_filename = ''.join(
+            [consts.YARDSTICK_ROOT_PATH,
+             'yardstick/resources/files/yardstick_key-',
+             self.test_context._name_task_id])
+        mock_genkeys.assert_called_once_with(key_filename)
+        mock_path_exists.assert_called_with(key_filename)
+
+        mock_call_gen_keys = mock.call.gen_keys(key_filename)
+        mock_call_add_resources = (
+            mock.call._add_resources_to_template('heat_template'))
+        self.assertTrue(mock_manager.mock_calls.index(mock_call_gen_keys) <
+                        mock_manager.mock_calls.index(mock_call_add_resources))
 
     def test_check_for_context(self):
         pass
@@ -326,6 +380,7 @@ class HeatContextTestCase(unittest.TestCase):
             u'e-network_id': u'net987',
         }
         server = mock.MagicMock()
+        server.private_ip = None
         server.ports = OrderedDict([
             ('a', [{'stack_name': 'b', 'port': 'port_a'}]),
             ('c', [{'stack_name': 'd', 'port': 'port_c'},
index 76c4da5..20cc00b 100644 (file)
@@ -239,6 +239,7 @@ class ServerTestCase(unittest.TestCase):
         mock_network.vnic_type = 'normal'
         mock_network.subnet_stack_name = 'some-network-stack-subnet'
         mock_network.provider = 'sriov'
+        mock_network.net_flags = {}
         mock_network.external_network = 'ext_net'
         mock_network.router = model.Router('some-router', 'some-network', self.mock_context,
                                            'ext_net')
@@ -248,9 +249,7 @@ class ServerTestCase(unittest.TestCase):
 
         mock_template.add_port.assert_called_with(
             'some-server-some-network-port',
-            mock_network.stack_name,
-            mock_network.subnet_stack_name,
-            mock_network.vnic_type,
+            mock_network,
             sec_group_id=self.mock_context.secgroup_name,
             provider=mock_network.provider,
             allowed_address_pairs=mock_network.allowed_address_pairs)
@@ -511,6 +510,7 @@ class ServerTestCase(unittest.TestCase):
         mock_network = mock.Mock()
         mock_network.allowed_address_pairs = ["1", "2"]
         mock_network.vnic_type = 'normal'
+        mock_network.net_flags = {}
         mock_network.configure_mock(name='some-network', stack_name='some-network-stack',
                                     subnet_stack_name='some-network-stack-subnet',
                                     provider='some-provider')
@@ -520,9 +520,7 @@ class ServerTestCase(unittest.TestCase):
 
         mock_template.add_port.assert_called_with(
             'ServerFlavor-2-some-network-port',
-            mock_network.stack_name,
-            mock_network.subnet_stack_name,
-            mock_network.vnic_type,
+            mock_network,
             provider=mock_network.provider,
             sec_group_id=self.mock_context.secgroup_name,
             allowed_address_pairs=mock_network.allowed_address_pairs)
@@ -554,6 +552,7 @@ class ServerTestCase(unittest.TestCase):
         mock_network.name = 'some-network'
         mock_network.stack_name = 'some-network-stack'
         mock_network.subnet_stack_name = 'some-network-stack-subnet'
+        mock_network.net_flags = {}
 
         test_server._add_instance(mock_template, 'ServerFlavor-3',
                                   [mock_network], 'hints')
diff --git a/yardstick/tests/unit/benchmark/scenarios/networking/test_moongen_testpmd.py b/yardstick/tests/unit/benchmark/scenarios/networking/test_moongen_testpmd.py
new file mode 100644 (file)
index 0000000..620155c
--- /dev/null
@@ -0,0 +1,353 @@
+#!/usr/bin/env python
+
+# Copyright 2017 Nokia
+#
+# 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.
+
+# Unittest for yardstick.benchmark.scenarios.networking.MoongenTestPMD
+
+from __future__ import absolute_import
+try:
+    from unittest import mock
+except ImportError:
+    import mock
+import unittest
+
+from yardstick.benchmark.scenarios.networking import moongen_testpmd
+
+
+@mock.patch('yardstick.benchmark.scenarios.networking.moongen_testpmd.subprocess')
+class MoongenTestPMDTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self.ctx = {
+            "host": {
+                "ip": "10.229.47.137",
+                "user": "ubuntu",
+                "password": "ubuntu",
+            },
+        }
+        self.TestPMDargs = {
+            'task_id': "1234-5678",
+            'options': {
+                'multistream': 1,
+                'frame_size': 1024,
+                'testpmd_queue': 2,
+                'trafficgen_port1': 'ens5',
+                'trafficgen_port2': 'ens6',
+                'moongen_host_user': 'root',
+                'moongen_host_passwd': 'root',
+                'moongen_host_ip': '10.5.201.151',
+                'moongen_dir': '/home/lua-trafficgen',
+                'moongen_runBidirec': 'true',
+                'Package_Loss': 0,
+                'SearchRuntime': 60,
+                'moongen_port1_mac': '88:cf:98:2f:4d:ed',
+                'moongen_port2_mac': '88:cf:98:2f:4d:ee',
+                'forward_type': 'testpmd',
+            },
+            'sla': {
+                'metrics': 'throughput_rx_mpps',
+                'throughput_rx_mpps': 0.5,
+                'action': 'monitor',
+            }
+        }
+        self.L2fwdargs = {
+            'task_id': "1234-5678",
+            'options': {
+                'multistream': 1,
+                'frame_size': 1024,
+                'testpmd_queue': 2,
+                'trafficgen_port1': 'ens5',
+                'trafficgen_port2': 'ens6',
+                'moongen_host_user': 'root',
+                'moongen_host_passwd': 'root',
+                'moongen_host_ip': '10.5.201.151',
+                'moongen_dir': '/home/lua-trafficgen',
+                'moongen_runBidirec': 'true',
+                'Package_Loss': 0,
+                'SearchRuntime': 60,
+                'moongen_port1_mac': '88:cf:98:2f:4d:ed',
+                'moongen_port2_mac': '88:cf:98:2f:4d:ee',
+                'forward_type': 'l2fwd',
+            },
+            'sla': {
+                'metrics': 'throughput_rx_mpps',
+                'throughput_rx_mpps': 0.5,
+                'action': 'monitor',
+            }
+        }
+
+        self._mock_ssh = mock.patch(
+            'yardstick.benchmark.scenarios.networking.moongen_testpmd.ssh')
+        self.mock_ssh = self._mock_ssh.start()
+
+        self.addCleanup(self._cleanup)
+
+    def _cleanup(self):
+        self._mock_ssh.stop()
+
+    def test_MoongenTestPMD_setup(self, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.TestPMDargs, self.ctx)
+
+        # setup() specific mocks
+        mock_subprocess.call().execute.return_value = None
+
+        p.setup()
+        self.assertIsNotNone(p.client)
+        self.assertTrue(p.setup_done)
+
+    def test_MoongenTestPMD_teardown(self, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.TestPMDargs, self.ctx)
+
+        # setup() specific mocks
+        mock_subprocess.call().execute.return_value = None
+
+        p.setup()
+        self.assertIsNotNone(p.client)
+        self.assertTrue(p.setup_done)
+
+        p.teardown()
+        self.assertFalse(p.setup_done)
+
+    def test_MoongenTestPMD_l2fwd_is_forward_setup_no(self, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.L2fwdargs, self.ctx)
+
+        # setup() specific mocks
+        mock_subprocess.call().execute.return_value = None
+
+        p.setup()
+        self.assertIsNotNone(p.client)
+        self.assertTrue(p.setup_done)
+
+        # is_dpdk_setup() specific mocks
+        self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+
+        result = p._is_forward_setup()
+        self.assertFalse(result)
+
+    def test_MoongenTestPMD_l2fwd_is_forward_setup_yes(self, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.L2fwdargs, self.ctx)
+
+        # setup() specific mocks
+        mock_subprocess.call().execute.return_value = None
+
+        p.setup()
+        self.assertIsNotNone(p.client)
+        self.assertTrue(p.setup_done)
+
+        # is_dpdk_setup() specific mocks
+        self.mock_ssh.SSH.from_node().execute.return_value = (0, 'dummy', '')
+
+        result = p._is_forward_setup()
+        self.assertTrue(result)
+
+    def test_MoongenTestPMD_testpmd_is_forward_setup_no(self, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.TestPMDargs, self.ctx)
+
+        # setup() specific mocks
+        mock_subprocess.call().execute.return_value = None
+
+        p.setup()
+        self.assertIsNotNone(p.client)
+        self.assertTrue(p.setup_done)
+
+        # is_dpdk_setup() specific mocks
+        self.mock_ssh.SSH.from_node().execute.return_value = (0, 'dummy', '')
+
+        result = p._is_forward_setup()
+        self.assertFalse(result)
+
+    def test_MoongenTestPMD_testpmd_is_forward_setup_yes(self, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.TestPMDargs, self.ctx)
+
+        # setup() specific mocks
+        mock_subprocess.call().execute.return_value = None
+
+        p.setup()
+        self.assertIsNotNone(p.client)
+        self.assertTrue(p.setup_done)
+
+        # is_dpdk_setup() specific mocks
+        self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+
+        result = p._is_forward_setup()
+        self.assertTrue(result)
+
+    @mock.patch('time.sleep')
+    def test_MoongenTestPMD_testpmd_forward_setup_first(self, _, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.TestPMDargs, self.ctx)
+
+        # setup() specific mocks
+        mock_subprocess.call().execute.return_value = None
+
+        p.setup()
+        self.assertIsNotNone(p.client)
+        self.assertTrue(p.setup_done)
+
+        # is_dpdk_setup() specific mocks
+        self.mock_ssh.SSH.from_node().execute.return_value = (0, 'dummy', '')
+
+        p.forward_setup()
+        self.assertFalse(p._is_forward_setup())
+        self.assertTrue(p.forward_setup_done)
+
+    @mock.patch('time.sleep')
+    def test_MoongenTestPMD_testpmd_dpdk_setup_next(self, _, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.TestPMDargs, self.ctx)
+
+        # setup() specific mocks
+        self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+        mock_subprocess.call().execute.return_value = None
+
+        p.setup()
+        self.assertIsNotNone(p.client)
+        self.assertTrue(p.setup_done)
+
+        p.forward_setup()
+        self.assertTrue(p._is_forward_setup())
+        self.assertTrue(p.forward_setup_done)
+
+    @mock.patch('time.sleep')
+    def test_MoongenTestPMD_l2fwd_forward_setup_first(self, _, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.L2fwdargs, self.ctx)
+
+        # setup() specific mocks
+        mock_subprocess.call().execute.return_value = None
+
+        p.setup()
+        self.assertIsNotNone(p.client)
+        self.assertTrue(p.setup_done)
+
+        # is_dpdk_setup() specific mocks
+        self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+
+        p.forward_setup()
+        self.assertFalse(p._is_forward_setup())
+        self.assertTrue(p.forward_setup_done)
+
+    @mock.patch('time.sleep')
+    def test_MoongenTestPMD_l2fwd_dpdk_setup_next(self, _, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.L2fwdargs, self.ctx)
+
+        # setup() specific mocks
+        self.mock_ssh.SSH.from_node().execute.return_value = (0, 'dummy', '')
+        mock_subprocess.call().execute.return_value = None
+
+        p.setup()
+        self.assertIsNotNone(p.client)
+        self.assertTrue(p.setup_done)
+
+        p.forward_setup()
+        self.assertTrue(p._is_forward_setup())
+        self.assertTrue(p.forward_setup_done)
+
+    def test_moongen_testpmd_generate_config_file(self, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.TestPMDargs, self.ctx)
+
+        # setup() specific mocks
+        mock_subprocess.call().execute.return_value = None
+
+        p.generate_config_file(frame_size=1, multistream=1,
+                               runBidirec="True", tg_port1_vlan=1,
+                               tg_port2_vlan=2, SearchRuntime=1,
+                               Package_Loss=0)
+        self.assertTrue(p.CONFIG_FILE)
+
+    def test_moongen_testpmd_result_to_data_match(self, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.TestPMDargs, self.ctx)
+
+        mock_subprocess.call().execute.return_value = None
+        result = ("[REPORT]Device 1->0: Tx frames: 420161490 Rx Frames: 420161490"
+                  " frame loss: 0, 0.000000% Rx Mpps: 7.002708\n[REPORT]      "
+                  "total: Tx frames: 840321216 Rx Frames: 840321216 frame loss: "
+                  "0, 0.000000% Tx Mpps: 14.005388 Rx Mpps: 14.005388\n'")
+        p.result_to_data(result=result)
+        self.assertTrue(p.TO_DATA)
+
+    def test_moongen_testpmd_result_to_data_not_match(self, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.TestPMDargs, self.ctx)
+
+        mock_subprocess.call().execute.return_value = None
+        result = ("")
+        p.result_to_data(result=result)
+        self.assertTrue(p.TO_DATA)
+
+    @mock.patch('time.sleep')
+    def test_moongen_testpmd_run_ok(self, _, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.TestPMDargs, self.ctx)
+        p.setup_done = True
+        p.forward_setup_done = True
+        p.setup()
+
+        # run() specific mocks
+        p.server = self.mock_ssh.SSH.from_node()
+        mock_subprocess.call().execute.return_value = None
+        mock_subprocess.call().execute.return_value = None
+        result = ("[REPORT]Device 1->0: Tx frames: 420161490 Rx Frames: 420161490"
+                  " frame loss: 0, 0.000000% Rx Mpps: 7.002708\n[REPORT]      "
+                  "total: Tx frames: 840321216 Rx Frames: 840321216 frame loss: "
+                  "0, 0.000000% Tx Mpps: 14.005388 Rx Mpps: 14.005388\n'")
+        self.mock_ssh.SSH.from_node().execute.return_value = (
+            0, result, '')
+
+        test_result = {}
+        p.run(test_result)
+
+        self.assertEqual(test_result['rx_mpps'], 14.005388)
+
+    def test_moongen_testpmd_run_falied_vsperf_execution(self, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.TestPMDargs, self.ctx)
+
+        # setup() specific mocks
+        self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+        mock_subprocess.call().execute.return_value = None
+
+        p.setup()
+        self.assertIsNotNone(p.client)
+        self.assertTrue(p.setup_done)
+
+        # run() specific mocks
+        mock_subprocess.call().execute.return_value = None
+        mock_subprocess.call().execute.return_value = None
+        self.mock_ssh.SSH.from_node().execute.return_value = (1, '', '')
+
+        result = {}
+        self.assertRaises(RuntimeError, p.run, result)
+
+    def test_moongen_testpmd_run_falied_csv_report(self, mock_subprocess):
+        p = moongen_testpmd.MoongenTestPMD(self.TestPMDargs, self.ctx)
+
+        # setup() specific mocks
+        self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+        mock_subprocess.call().execute.return_value = None
+
+        p.setup()
+        self.assertIsNotNone(p.client)
+        self.assertTrue(p.setup_done)
+
+        # run() specific mocks
+        mock_subprocess.call().execute.return_value = None
+        mock_subprocess.call().execute.return_value = None
+        self.mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+        self.mock_ssh.SSH.from_node().execute.return_value = (1, '', '')
+
+        result = {}
+        self.assertRaises(RuntimeError, p.run, result)
+
+def main():
+    unittest.main()
+
+
+if __name__ == '__main__':
+    main()
index f47d1ca..f149cee 100644 (file)
@@ -61,6 +61,22 @@ class FioTestCase(unittest.TestCase):
         }
         args = {'options': options}
         p = fio.Fio(args, self.ctx)
+        mock_ssh.SSH.from_node().execute.return_value = (0, '/dev/vdb', '')
+        p.setup()
+
+        mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+        self.assertIsNotNone(p.client)
+        self.assertTrue(p.setup_done)
+
+    def test_fio_job_file_no_disk__setup(self, mock_ssh):
+
+        options = {
+            'job_file': 'job_file.ini',
+            'directory': '/FIO_Test'
+        }
+        args = {'options': options}
+        p = fio.Fio(args, self.ctx)
+        mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
         p.setup()
 
         mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
index 9ab8740..aae2487 100644 (file)
@@ -272,10 +272,18 @@ class HeatTemplateTestCase(unittest.TestCase):
         heat_template.add_subnet("subnet2", "network2", "cidr2")
         heat_template.add_router("router1", "gw1", "subnet1")
         heat_template.add_router_interface("router_if1", "router1", "subnet1")
-        heat_template.add_port("port1", "network1", "subnet1", "normal")
-        heat_template.add_port("port2", "network2", "subnet2", "normal",
+        network1 = mock.MagicMock()
+        network1.stack_name = "network1"
+        network1.subnet_stack_name = "subnet1"
+        network1.vnic_type = "normal"
+        network2 = mock.MagicMock()
+        network2.stack_name = "network2"
+        network2.subnet_stack_name = "subnet2"
+        network2.vnic_type = "normal"
+        heat_template.add_port("port1", network1)
+        heat_template.add_port("port2", network2,
                                sec_group_id="sec_group1", provider="not-sriov")
-        heat_template.add_port("port3", "network2", "subnet2", "normal",
+        heat_template.add_port("port3", network2,
                                sec_group_id="sec_group1", provider="sriov")
         heat_template.add_floating_ip("floating_ip1", "network1", "port1",
                                       "router_if1")