diff options
33 files changed, 1640 insertions, 7 deletions
diff --git a/docs/testing/user/userguide/opnfv_yardstick_tc056.rst b/docs/testing/user/userguide/opnfv_yardstick_tc056.rst new file mode 100644 index 000000000..01aa99ac2 --- /dev/null +++ b/docs/testing/user/userguide/opnfv_yardstick_tc056.rst @@ -0,0 +1,149 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International +.. License. +.. http://creativecommons.org/licenses/by/4.0 +.. (c) OPNFV, Yin Kanglin and others. +.. 14_ykl@tongji.edu.cn + +************************************* +Yardstick Test Case Description TC056 +************************************* + ++-----------------------------------------------------------------------------+ +|OpenStack Controller Messaging Queue Service High Availability | ++==============+==============================================================+ +|test case id | OPNFV_YARDSTICK_TC056:OpenStack Controller Messaging Queue | +| | Service High Availability | ++--------------+--------------------------------------------------------------+ +|test purpose | This test case will verify the high availability of the | +| | messaging queue service(RabbitMQ) that supports OpenStack on | +| | controller node. When messaging queue service(which is | +| | active) of a specified controller node is killed, the test | +| | case will check whether messaging queue services(which are | +| | standby) on other controller nodes will be switched active, | +| | and whether the cluster manager on attacked the controller | +| | node will restart the stopped messaging queue. | ++--------------+--------------------------------------------------------------+ +|test method | This test case kills the processes of messaging queue | +| | service on a selected controller node, then checks whether | +| | the request of the related Openstack command is OK and the | +| | killed processes are recovered. | ++--------------+--------------------------------------------------------------+ +|attackers | In this test case, an attacker called "kill-process" is | +| | needed. This attacker includes three parameters: | +| | 1) fault_type: which is used for finding the attacker's | +| | scripts. It should be always set to "kill-process" in this | +| | test case. | +| | 2) process_name: which is the process name of the specified | +| | OpenStack service. If there are multiple processes use the | +| | same name on the host, all of them are killed by this | +| | attacker. | +| | In this case, this parameter should always set to "rabbitmq".| +| | 3) host: which is the name of a control node being attacked. | +| | | +| | e.g. | +| | -fault_type: "kill-process" | +| | -process_name: "rabbitmq-server" | +| | -host: node1 | +| | | ++--------------+--------------------------------------------------------------+ +|monitors | In this test case, two kinds of monitor are needed: | +| | 1. the "openstack-cmd" monitor constantly request a specific | +| | Openstack command, which needs two parameters: | +| | 1) monitor_type: which is used for finding the monitor class | +| | and related scritps. It should be always set to | +| | "openstack-cmd" for this monitor. | +| | 2) command_name: which is the command name used for request. | +| | | +| | 2. the "process" monitor check whether a process is running | +| | on a specific node, which needs three parameters: | +| | 1) monitor_type: which used for finding the monitor class | +| | and related scripts. It should be always set to "process" | +| | for this monitor. | +| | 2) process_name: which is the process name for monitor | +| | 3) host: which is the name of the node runing the process | +| | In this case, the command_name of monitor1 should be | +| | services that will use the messaging queue(current nova, | +| | neutron, cinder ,heat and ceilometer are using RabbitMQ) | +| | , and the process-name of monitor2 should be "rabbitmq", | +| | for example: | +| | | +| | e.g. | +| | monitor1-1: | +| | -monitor_type: "openstack-cmd" | +| | -command_name: "openstack image list" | +| | monitor1-2: | +| | -monitor_type: "openstack-cmd" | +| | -command_name: "openstack network list" | +| | monitor1-3: | +| | -monitor_type: "openstack-cmd" | +| | -command_name: "openstack volume list" | +| | monitor2: | +| | -monitor_type: "process" | +| | -process_name: "rabbitmq" | +| | -host: node1 | +| | | ++--------------+--------------------------------------------------------------+ +|metrics | In this test case, there are two metrics: | +| | 1)service_outage_time: which indicates the maximum outage | +| | time (seconds) of the specified Openstack command request. | +| | 2)process_recover_time: which indicates the maximum time | +| | (seconds) from the process being killed to recovered | +| | | ++--------------+--------------------------------------------------------------+ +|test tool | Developed by the project. Please see folder: | +| | "yardstick/benchmark/scenarios/availability/ha_tools" | +| | | ++--------------+--------------------------------------------------------------+ +|references | ETSI NFV REL001 | +| | | ++--------------+--------------------------------------------------------------+ +|configuration | This test case needs two configuration files: | +| | 1) test case file:opnfv_yardstick_tc056.yaml | +| | -Attackers: see above "attackers" description | +| | -waiting_time: which is the time (seconds) from the process | +| | being killed to stoping monitors the monitors | +| | -Monitors: see above "monitors" description | +| | -SLA: see above "metrics" description | +| | | +| | 2)POD file: pod.yaml | +| | The POD configuration should record on pod.yaml first. | +| | the "host" item in this test case will use the node name in | +| | the pod.yaml. | +| | | ++--------------+--------------------------------------------------------------+ +|test sequence | description and expected result | +| | | ++--------------+--------------------------------------------------------------+ +|step 1 | start monitors: | +| | each monitor will run with independently process | +| | | +| | Result: The monitor info will be collected. | +| | | ++--------------+--------------------------------------------------------------+ +|step 2 | do attacker: connect the host through SSH, and then execute | +| | the kill process script with param value specified by | +| | "process_name" | +| | | +| | Result: Process will be killed. | +| | | ++--------------+--------------------------------------------------------------+ +|step 3 | stop monitors after a period of time specified by | +| | "waiting_time" | +| | | +| | Result: The monitor info will be aggregated. | +| | | ++--------------+--------------------------------------------------------------+ +|step 4 | verify the SLA | +| | | +| | Result: The test case is passed or not. | +| | | ++--------------+--------------------------------------------------------------+ +|post-action | It is the action when the test cases exist. It will check | +| | the status of the specified process on the host, and restart | +| | the process if it is not running for next test cases. | +| | | ++--------------+--------------------------------------------------------------+ +|test verdict | Fails only if SLA is not passed, or if there is a test case | +| | execution problem. | +| | | ++--------------+--------------------------------------------------------------+ diff --git a/docs/testing/user/userguide/opnfv_yardstick_tc057.rst b/docs/testing/user/userguide/opnfv_yardstick_tc057.rst new file mode 100644 index 000000000..2a4ce40c0 --- /dev/null +++ b/docs/testing/user/userguide/opnfv_yardstick_tc057.rst @@ -0,0 +1,165 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International +.. License. +.. http://creativecommons.org/licenses/by/4.0 +.. (c) OPNFV, Yin Kanglin and others. +.. 14_ykl@tongji.edu.cn + +************************************* +Yardstick Test Case Description TC057 +************************************* + ++-----------------------------------------------------------------------------+ +|OpenStack Controller Cluster Management Service High Availability | ++==============+==============================================================+ +|test case id | | ++--------------+--------------------------------------------------------------+ +|test purpose | This test case will verify the quorum configuration of the | +| | cluster manager(pacemaker) on controller nodes. When a | +| | controller node , which holds all active application | +| | resources, failed to communicate with other cluster nodes | +| | (via corosync), the test case will check whether the standby | +| | application resources will take place of those active | +| | application resources which should be regarded to be down in | +| | the cluster manager. | ++--------------+--------------------------------------------------------------+ +|test method | This test case kills the processes of cluster messaging | +| | service(corosync) on a selected controller node(the node | +| | holds the active application resources), then checks whether | +| | active application resources are switched to other | +| | controller nodes and whether the Openstack commands are OK. | ++--------------+--------------------------------------------------------------+ +|attackers | In this test case, an attacker called "kill-process" is | +| | needed. This attacker includes three parameters: | +| | 1) fault_type: which is used for finding the attacker's | +| | scripts. It should be always set to "kill-process" in this | +| | test case. | +| | 2) process_name: which is the process name of the load | +| | balance service. If there are multiple processes use the | +| | same name on the host, all of them are killed by this | +| | attacker. | +| | 3) host: which is the name of a control node being attacked. | +| | | +| | In this case, this process name should set to "corosync" , | +| | for example | +| | -fault_type: "kill-process" | +| | -process_name: "corosync" | +| | -host: node1 | ++--------------+--------------------------------------------------------------+ +|monitors | In this test case, a kind of monitor is needed: | +| | 1. the "openstack-cmd" monitor constantly request a specific | +| | Openstack command, which needs two parameters: | +| | 1) monitor_type: which is used for finding the monitor class | +| | and related scripts. It should be always set to | +| | "openstack-cmd" for this monitor. | +| | 2) command_name: which is the command name used for request | +| | | +| | In this case, the command_name of monitor1 should be services| +| | that are managed by the cluster manager. (Since rabbitmq and | +| | haproxy are managed by pacemaker, most Openstack Services | +| | can be used to check high availability in this case) | +| | | +| | (e.g.) | +| | monitor1: | +| | -monitor_type: "openstack-cmd" | +| | -command_name: "nova image-list" | +| | monitor2: | +| | -monitor_type: "openstack-cmd" | +| | -command_name: "neutron router-list" | +| | monitor3: | +| | -monitor_type: "openstack-cmd" | +| | -command_name: "heat stack-list" | +| | monitor4: | +| | -monitor_type: "openstack-cmd" | +| | -command_name: "cinder list" | +| | | ++--------------+--------------------------------------------------------------+ +|checkers | In this test case, a checker is needed, the checker will | +| | the status of application resources in pacemaker and the | +| | checker have three parameters: | +| | 1) checker_type: which is used for finding the result | +| | checker class and related scripts. In this case the checker | +| | type will be "pacemaker-check-resource" | +| | 2) resource_name: the application resource name | +| | 3) resource_status: the expected status of the resource | +| | 4) expectedValue: the expected value for the output of the | +| | checker script, in the case the expected value will be the | +| | identifier in the cluster manager | +| | 3) condition: whether the expected value is in the output of | +| | checker script or is totally same with the output. | +| | (note: pcs is required to installed on controller node in | +| | order to run this checker) | +| | | +| | (e.g.) | +| | checker1: | +| | -checker_type: "pacemaker-check-resource" | +| | -resource_name: "p_rabbitmq-server" | +| | -resource_status: "Stopped" | +| | -expectedValue: "node-1" | +| | -condition: "in" | +| | checker2: | +| | -checker_type: "pacemaker-check-resource" | +| | -resource_name: "p_rabbitmq-server" | +| | -resource_status: "Master" | +| | -expectedValue: "node-2" | +| | -condition: "in" | ++--------------+--------------------------------------------------------------+ +|metrics | In this test case, there are two metrics: | +| | 1)service_outage_time: which indicates the maximum outage | +| | time (seconds) of the specified Openstack command request. | ++--------------+--------------------------------------------------------------+ +|test tool | None. Self-developed. | ++--------------+--------------------------------------------------------------+ +|references | ETSI NFV REL001 | ++--------------+--------------------------------------------------------------+ +|configuration | This test case needs two configuration files: | +| | 1) test case file: opnfv_yardstick_tc057.yaml | +| | -Attackers: see above "attackers" description | +| | -Monitors: see above "monitors" description | +| | -Checkers: see above "checkers" description | +| | -Steps: the test case execution step, see "test sequence" | +| | description below | +| | | +| | 2)POD file: pod.yaml | +| | The POD configuration should record on pod.yaml first. | +| | the "host" item in this test case will use the node name in | +| | the pod.yaml. | ++--------------+------+----------------------------------+--------------------+ +|test sequence | description and expected result | +| | | ++--------------+--------------------------------------------------------------+ +|step 1 | start monitors: | +| | each monitor will run with independently process | +| | | +| | Result: The monitor info will be collected. | +| | | ++--------------+--------------------------------------------------------------+ +|step 2 | do attacker: connect the host through SSH, and then execute | +| | the kill process script with param value specified by | +| | "process_name" | +| | | +| | Result: Process will be killed. | +| | | ++--------------+--------------------------------------------------------------+ +|step 3 | do checker: check whether the status of application | +| | resources on different nodes are updated | +| | | ++--------------+--------------------------------------------------------------+ +|step 4 | stop monitors after a period of time specified by | +| | "waiting_time" | +| | | +| | Result: The monitor info will be aggregated. | +| | | ++--------------+--------------------------------------------------------------+ +|step 5 | verify the SLA | +| | | +| | Result: The test case is passed or not. | +| | | ++--------------+------+----------------------------------+--------------------+ +|post-action | It is the action when the test cases exist. It will check the| +| | status of the cluster messaging process(corosync) on the | +| | host, and restart the process if it is not running for next | +| | test cases | ++--------------+------+----------------------------------+--------------------+ +|test verdict | Fails only if SLA is not passed, or if there is a test case | +| | execution problem. | ++--------------+--------------------------------------------------------------+ diff --git a/docs/testing/user/userguide/opnfv_yardstick_tc058.rst b/docs/testing/user/userguide/opnfv_yardstick_tc058.rst new file mode 100644 index 000000000..fb9a4c2d1 --- /dev/null +++ b/docs/testing/user/userguide/opnfv_yardstick_tc058.rst @@ -0,0 +1,148 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International +.. License. +.. http://creativecommons.org/licenses/by/4.0 +.. (c) OPNFV, Yin Kanglin and others. +.. 14_ykl@tongji.edu.cn + +************************************* +Yardstick Test Case Description TC058 +************************************* + ++-----------------------------------------------------------------------------+ +|OpenStack Controller Virtual Router Service High Availability | ++==============+==============================================================+ +|test case id | OPNFV_YARDSTICK_TC058:OpenStack Controller Virtual Router | +| | Service High Availability | ++--------------+--------------------------------------------------------------+ +|test purpose | This test case will verify the high availability of virtual | +| | routers(L3 agent) on controller node. When a virtual router | +| | service on a specified controller node is shut down, this | +| | test case will check whether the network of virtual machines | +| | will be affected, and whether the attacked virtual router | +| | service will be recovered. | ++--------------+--------------------------------------------------------------+ +|test method | This test case kills the processes of virtual router service | +| | (l3-agent) on a selected controller node(the node holds the | +| | active l3-agent), then checks whether the network routing | +| | of virtual machines is OK and whether the killed service | +| | will be recovered. | ++--------------+--------------------------------------------------------------+ +|attackers | In this test case, an attacker called "kill-process" is | +| | needed. This attacker includes three parameters: | +| | 1) fault_type: which is used for finding the attacker's | +| | scripts. It should be always set to "kill-process" in this | +| | test case. | +| | 2) process_name: which is the process name of the load | +| | balance service. If there are multiple processes use the | +| | same name on the host, all of them are killed by this | +| | attacker. | +| | 3) host: which is the name of a control node being attacked. | +| | | +| | In this case, this process name should set to "l3agent" , | +| | for example | +| | -fault_type: "kill-process" | +| | -process_name: "l3agent" | +| | -host: node1 | ++--------------+--------------------------------------------------------------+ +|monitors | In this test case, two kinds of monitor are needed: | +| | 1. the "ip_status" monitor that pings a specific ip to check | +| | the connectivity of this ip, which needs two parameters: | +| | 1) monitor_type: which is used for finding the monitor class | +| | and related scripts. It should be always set to "ip_status" | +| | for this monitor. | +| | 2) ip_address: The ip to be pinged. In this case, ip_address | +| | will be either an ip address of external network or an ip | +| | address of a virtual machine. | +| | 3) host: The node on which ping will be executed, in this | +| | case the host will be a virtual machine. | +| | | +| | 2. the "process" monitor check whether a process is running | +| | on a specific node, which needs three parameters: | +| | 1) monitor_type: which used for finding the monitor class | +| | and related scripts. It should be always set to "process" | +| | for this monitor. | +| | 2) process_name: which is the process name for monitor. In | +| | this case, the process-name of monitor2 should be "l3agent" | +| | 3) host: which is the name of the node running the process | +| | | +| | e.g. | +| | monitor1-1: | +| | -monitor_type: "ip_status" | +| | -host: 172.16.0.11 | +| | -ip_address: 172.16.1.11 | +| | monitor1-2: | +| | -monitor_type: "ip_status" | +| | -host: 172.16.0.11 | +| | -ip_address: 8.8.8.8 | +| | monitor2: | +| | -monitor_type: "process" | +| | -process_name: "l3agent" | +| | -host: node1 | ++--------------+--------------------------------------------------------------+ +|metrics | In this test case, there are two metrics: | +| | 1)service_outage_time: which indicates the maximum outage | +| | time (seconds) of the specified Openstack command request. | +| | 2)process_recover_time: which indicates the maximum time | +| | (seconds) from the process being killed to recovered | ++--------------+--------------------------------------------------------------+ +|test tool | None. Self-developed. | ++--------------+--------------------------------------------------------------+ +|references | ETSI NFV REL001 | ++--------------+--------------------------------------------------------------+ +|configuration | This test case needs two configuration files: | +| | 1) test case file: opnfv_yardstick_tc058.yaml | +| | -Attackers: see above "attackers" description | +| | -Monitors: see above "monitors" description | +| | -Steps: the test case execution step, see "test sequence" | +| | description below | +| | | +| | 2)POD file: pod.yaml | +| | The POD configuration should record on pod.yaml first. | +| | the "host" item in this test case will use the node name in | +| | the pod.yaml. | ++--------------+------+----------------------------------+--------------------+ +|test sequence | description and expected result | +| | | ++--------------+--------------------------------------------------------------+ +|pre-test | The test case image needs to be installed into Glance | +|conditions | with cachestat included in the image. | +| | | ++--------------+--------------------------------------------------------------+ +|step 1 | Two host VMs are booted, these two hosts are in two different| +| | networks, the networks are connected by a virtual router | +| | | ++--------------+--------------------------------------------------------------+ +|step 1 | start monitors: | +| | each monitor will run with independently process | +| | | +| | Result: The monitor info will be collected. | +| | | ++--------------+--------------------------------------------------------------+ +|step 2 | do attacker: connect the host through SSH, and then execute | +| | the kill process script with param value specified by | +| | "process_name" | +| | | +| | Result: Process will be killed. | +| | | ++--------------+--------------------------------------------------------------+ +|step 4 | stop monitors after a period of time specified by | +| | "waiting_time" | +| | | +| | Result: The monitor info will be aggregated. | +| | | ++--------------+--------------------------------------------------------------+ +|step 5 | verify the SLA | +| | | +| | Result: The test case is passed or not. | +| | | ++--------------+------+----------------------------------+--------------------+ +|post-action | It is the action when the test cases exist. It will check | +| | the status of the specified process on the host, and restart | +| | the process if it is not running for next test cases. | +| | Virtual machines and network created in the test case will | +| | be destoryed. | +| | | ++--------------+------+----------------------------------+--------------------+ +|test verdict | Fails only if SLA is not passed, or if there is a test case | +| | execution problem. | ++--------------+--------------------------------------------------------------+ diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc056.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc056.yaml new file mode 100644 index 000000000..7f1dc1010 --- /dev/null +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc056.yaml @@ -0,0 +1,81 @@ +############################################################################## +# Copyright (c) 2017 14_ykl@tongji.edu.cn and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +--- + +schema: "yardstick:task:0.1" +description: > + Test case for TC056 :OpenStack Controller Messaging Queue Service High + Availability. + +{% set file = file or '/etc/yardstick/pod.yaml' %} +{% set attack_host = attack_host or 'node1' %} +{% set monitor_time = monitor_time or 10 %} +{% set monitor_number = monitor_number or 3 %} + +scenarios: +- + type: ServiceHA + options: + attackers: + - fault_type: "kill-process" + process_name: "rabbitmq-server" + host: {{attack_host}} + + monitors: + - monitor_type: "openstack-cmd" + command_name: "openstack image list" + monitor_time: {{monitor_time}} + monitor_number: {{monitor_number}} + sla: + max_outage_time: 5 + + - monitor_type: "openstack-cmd" + command_name: "openstack network list" + monitor_time: {{monitor_time}} + monitor_number: {{monitor_number}} + sla: + max_outage_time: 5 + + - monitor_type: "openstack-cmd" + command_name: "openstack volume list" + monitor_time: {{monitor_time}} + monitor_number: {{monitor_number}} + sla: + max_outage_time: 5 + + - monitor_type: "openstack-cmd" + command_name: "openstack stack list" + monitor_time: {{monitor_time}} + monitor_number: {{monitor_number}} + sla: + max_outage_time: 5 + + - monitor_type: "process" + process_name: "rabbitmq-server" + host: {{attack_host}} + monitor_time: 20 + sla: + max_recover_time: 20 + + nodes: + {{attack_host}}: {{attack_host}}.LF + + runner: + type: Duration + duration: 1 + sla: + outage_time: 5 + action: monitor + + +context: + type: Node + name: LF + file: {{file}} + diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc057.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc057.yaml new file mode 100644 index 000000000..322e2bd76 --- /dev/null +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc057.yaml @@ -0,0 +1,179 @@ +############################################################################## +# Copyright (c) 2017 14_ykl@tongji.edu.cn and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +--- + +schema: "yardstick:task:0.1" +description: > + Test case for TC057 :OpenStack Controller Cluster Management Service High + Availability; + This test case is written by scenario-based HA testing framework. + +{% set file = file or '/etc/yardstick/pod.yaml' %} +{% set vip_mgmt = vip_mgmt or 'vip__management' %} +{% set vip_vrouter = vip_vrouter or 'vip__vrouter' %} +{% set attack_host = attack_host or 'node1' %} +{% set check_host = check_host or 'node2' %} +{% set monitor_time = monitor_time or 10 %} +{% set monitor_number = monitor_number or 3 %} + +scenarios: + - + type: "GeneralHA" + options: + attackers: + - + fault_type: "general-attacker" + host: {{attack_host}} + key: "kill-process" + attack_key: "kill-corosync" + action_parameter: + process_name: "corosync" + + monitors: + - + monitor_type: "openstack-cmd" + key: "check-nova-service" + command_name: "openstack image list" + monitor_time: {{monitor_time}} + monitor_number: {{monitor_number}} + sla: + max_outage_time: 5 + + - + monitor_type: "openstack-cmd" + key: "check-neutron-service" + command_name: "openstack network list" + monitor_time: {{monitor_time}} + monitor_number: {{monitor_number}} + sla: + max_outage_time: 5 + + - + monitor_type: "openstack-cmd" + key: "check-keystone-service" + command_name: "openstack user list" + monitor_time: {{monitor_time}} + monitor_number: {{monitor_number}} + sla: + max_outage_time: 5 + + - + monitor_type: "openstack-cmd" + key: "check-heat-service" + command_name: "openstack stack list" + monitor_time: {{monitor_time}} + monitor_number: {{monitor_number}} + sla: + max_outage_time: 5 + + operations: + - + operation_type: "general-operation" + key: "get-mgmt-vip-host" + operation_key: "get-vip-host" + host: {{check_host}} + action_parameter: + vip_name: {{vip_mgmt}} + return_parameter: + all: "$vip_mgmt_host" + + - + operation_type: "general-operation" + key: "get-router-vip-host" + operation_key: "get-vip-host" + host: {{check_host}} + action_parameter: + vip_name: {{vip_vrouter}} + return_parameter: + all: "$vip_router_host" + + resultCheckers: + - + checker_type: "general-result-checker" + key: "check-rabbitmq-master" + checker_key: "pacemaker-resource-checker" + host: {{check_host}} + parameter: + resource_name: "p_rabbitmq-server" + resource_host: "$vip_mgmt_host" + expectedValue: "Masters" + condition: "in" + + - + checker_type: "general-result-checker" + key: "check-conntrackd-master" + checker_key: "pacemaker-resource-checker" + host: {{check_host}} + parameter: + resource_name: "p_conntrackd" + resource_host: "$vip_router_host" + expectedValue: "Masters" + condition: "in" + + steps: + - + actionKey: "kill-process" + actionType: "attacker" + index: 1 + + - + actionKey: "check-nova-service" + actionType: "monitor" + index: 2 + + - + actionKey: "check-neutron-service" + actionType: "monitor" + index: 3 + + - + actionKey: "check-keystone-service" + actionType: "monitor" + index: 4 + + - + actionKey: "check-heat-service" + actionType: "monitor" + index: 5 + + - + actionKey: "get-mgmt-vip-host" + actionType: "operation" + index: 6 + + - + actionKey: "check-rabbitmq-master" + actionType: "resultchecker" + index: 7 + + - + actionKey: "get-router-vip-host" + actionType: "operation" + index: 8 + + - + actionKey: "check-conntrackd-master" + actionType: "resultchecker" + index: 9 + + + nodes: + {{attack_host}}: {{attack_host}}.LF + {{check_host}}: {{check_host}}.LF + runner: + type: Duration + duration: 1 + sla: + outage_time: 5 + action: monitor + +context: + type: Node + name: LF + file: {{file}} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc058.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc058.yaml new file mode 100644 index 000000000..e9feb97f5 --- /dev/null +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc058.yaml @@ -0,0 +1,111 @@ +############################################################################## +# Copyright (c) 2017 14_ykl@tongji.edu.cn and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +--- + +schema: "yardstick:task:0.1" +description: > + Test case for TC058 :OpenStack Controller Virtual Router Service High + Availability; + This test case is written by scenario-based HA testing framework. + +{% set file = file or '/etc/yardstick/pod.yaml' %} +{% set image = image or 'yardstick-image' %} +{% set flavor = flavor or 'yardstick-flavor' %} +{% set attack_host = attack_host or 'node1' %} + +scenarios: + - + type: "GeneralHA" + options: + attackers: + - + fault_type: "kill-process" + host: {{attack_host}} + key: "kill-process" + process_name: "neutron-l3-agent" + + monitors: + - + monitor_type: "process" + process_name: "neutron-l3-agent" + host: {{attack_host}} + key: "monitor-recovery" + monitor_time: 20 + sla: + max_recover_time: 20 + + - + monitor_type: "general-monitor" + monitor_key: "ip-status" + key: "server-status" + monitor_time: 10 + sla: + max_outage_time: 5 + parameter: + ip_address: "$floating_ip" + + operations: + - + operation_type: "general-operation" + key: "get-floatingip" + operation_key: "get-floatingip" + action_parameter: + server_name: "tc058" + return_parameter: + all: "$floating_ip" + + + steps: + - + actionKey: "get-floatingip" + actionType: "operation" + index: 1 + - + actionKey: "kill-process" + actionType: "attacker" + index: 2 + + - + actionKey: "monitor-recovery" + actionType: "monitor" + index: 3 + + - + actionKey: "server-status" + actionType: "monitor" + index: 4 + + nodes: + {{attack_host}}: {{attack_host}}.LF + runner: + type: Duration + duration: 1 + sla: + outage_time: 5 + action: monitor + +contexts: +- + type: Node + name: LF + file: {{file}} + +- + name: demo + image: {{image}} + flavor: {{flavor}} + user: cirros + + servers: + tc058: + floating_ip: true + + networks: + test: + cidr: '10.0.1.0/24' diff --git a/tests/unit/benchmark/scenarios/lib/test_create_network.py b/tests/unit/benchmark/scenarios/lib/test_create_network.py new file mode 100644 index 000000000..8e7d8b5a1 --- /dev/null +++ b/tests/unit/benchmark/scenarios/lib/test_create_network.py @@ -0,0 +1,39 @@ +############################################################################## +# 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 +############################################################################## +import unittest +import mock +import paramiko + +from yardstick.benchmark.scenarios.lib.create_network import CreateNetwork + + +class CreateNetworkTestCase(unittest.TestCase): + + @mock.patch('yardstick.common.openstack_utils.get_neutron_client') + @mock.patch('yardstick.common.openstack_utils.create_neutron_net') + def test_create_network(self, mock_get_neutron_client, mock_create_neutron_net): + options = { + 'openstack_paras': { + 'name': 'yardstick_net', + 'admin_state_up': 'True' + } + } + args = {"options": options} + obj = CreateNetwork(args, {}) + obj.run({}) + self.assertTrue(mock_get_neutron_client.called) + self.assertTrue(mock_create_neutron_net.called) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/tests/unit/benchmark/scenarios/lib/test_create_port.py b/tests/unit/benchmark/scenarios/lib/test_create_port.py new file mode 100644 index 000000000..3b2aa2247 --- /dev/null +++ b/tests/unit/benchmark/scenarios/lib/test_create_port.py @@ -0,0 +1,36 @@ +############################################################################## +# 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 +############################################################################## +import unittest +import mock +import paramiko + +from yardstick.benchmark.scenarios.lib.create_port import CreatePort + + +class CreatePortTestCase(unittest.TestCase): + + @mock.patch('yardstick.common.openstack_utils.get_neutron_client') + def test_create_port(self, mock_get_neutron_client): + options = { + 'openstack_paras': { + 'name': 'yardstick_port' + } + } + args = {"options": options} + obj = CreatePort(args, {}) + obj.run({}) + self.assertTrue(mock_get_neutron_client.called) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/tests/unit/benchmark/scenarios/lib/test_create_router.py b/tests/unit/benchmark/scenarios/lib/test_create_router.py new file mode 100644 index 000000000..b956a3634 --- /dev/null +++ b/tests/unit/benchmark/scenarios/lib/test_create_router.py @@ -0,0 +1,39 @@ +############################################################################## +# 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 +############################################################################## +import unittest +import mock +import paramiko + +from yardstick.benchmark.scenarios.lib.create_router import CreateRouter + + +class CreateRouterTestCase(unittest.TestCase): + + @mock.patch('yardstick.common.openstack_utils.get_neutron_client') + @mock.patch('yardstick.common.openstack_utils.create_neutron_router') + def test_create_router(self, mock_get_neutron_client, mock_create_neutron_router): + options = { + 'openstack_paras': { + 'admin_state_up': 'True', + 'name': 'yardstick_router' + } + } + args = {"options": options} + obj = CreateRouter(args, {}) + obj.run({}) + self.assertTrue(mock_get_neutron_client.called) + self.assertTrue(mock_create_neutron_router.called) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/tests/unit/benchmark/scenarios/lib/test_create_sec_group.py b/tests/unit/benchmark/scenarios/lib/test_create_sec_group.py new file mode 100644 index 000000000..b962f7f0e --- /dev/null +++ b/tests/unit/benchmark/scenarios/lib/test_create_sec_group.py @@ -0,0 +1,39 @@ +############################################################################## +# 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 +############################################################################## +import unittest +import mock +import paramiko + +from yardstick.benchmark.scenarios.lib.create_sec_group import CreateSecgroup + + +class CreateSecGroupTestCase(unittest.TestCase): + + @mock.patch('yardstick.common.openstack_utils.get_neutron_client') + @mock.patch('yardstick.common.openstack_utils.create_security_group_full') + def test_create_sec_group(self, mock_get_neutron_client, mock_create_security_group_full): + options = { + 'openstack_paras': { + 'sg_name': 'yardstick_sec_group', + 'description': 'security group for yardstick manual VM' + } + } + args = {"options": options} + obj = CreateSecgroup(args, {}) + obj.run({}) + self.assertTrue(mock_get_neutron_client.called) + self.assertTrue(mock_create_security_group_full.called) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/tests/unit/benchmark/scenarios/lib/test_create_subnet.py b/tests/unit/benchmark/scenarios/lib/test_create_subnet.py new file mode 100644 index 000000000..0154755c4 --- /dev/null +++ b/tests/unit/benchmark/scenarios/lib/test_create_subnet.py @@ -0,0 +1,41 @@ +############################################################################## +# 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 +############################################################################## +import unittest +import mock +import paramiko + +from yardstick.benchmark.scenarios.lib.create_subnet import CreateSubnet + + +class CreateSubnetTestCase(unittest.TestCase): + + @mock.patch('yardstick.common.openstack_utils.get_neutron_client') + @mock.patch('yardstick.common.openstack_utils.create_neutron_subnet') + def test_create_subnet(self, mock_get_neutron_client, mock_create_neutron_subnet): + options = { + 'openstack_paras': { + 'network_id': '123-123-123', + 'name': 'yardstick_subnet', + 'cidr': '10.10.10.0/24', + 'ip_version': '4' + } + } + args = {"options": options} + obj = CreateSubnet(args, {}) + obj.run({}) + self.assertTrue(mock_get_neutron_client.called) + self.assertTrue(mock_create_neutron_subnet.called) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/tests/unit/benchmark/scenarios/networking/test_vsperf_dpdk.py b/tests/unit/benchmark/scenarios/networking/test_vsperf_dpdk.py index 3b9f99b08..de5bae2f3 100644 --- a/tests/unit/benchmark/scenarios/networking/test_vsperf_dpdk.py +++ b/tests/unit/benchmark/scenarios/networking/test_vsperf_dpdk.py @@ -28,8 +28,6 @@ from yardstick.benchmark.scenarios.networking import vsperf_dpdk @mock.patch('yardstick.benchmark.scenarios.networking.vsperf_dpdk.subprocess') @mock.patch('yardstick.benchmark.scenarios.networking.vsperf_dpdk.ssh') -@mock.patch("yardstick.benchmark.scenarios.networking.vsperf_dpdk.open", - mock.mock_open()) class VsperfDPDKTestCase(unittest.TestCase): def setUp(self): diff --git a/yardstick/benchmark/scenarios/availability/attacker_conf.yaml b/yardstick/benchmark/scenarios/availability/attacker_conf.yaml index aa144ab50..ee7ea7d83 100644 --- a/yardstick/benchmark/scenarios/availability/attacker_conf.yaml +++ b/yardstick/benchmark/scenarios/availability/attacker_conf.yaml @@ -40,3 +40,7 @@ stress-cpu: block-io: inject_script: ha_tools/disk/block_io.bash recovery_script: ha_tools/disk/recovery_disk_io.bash + +kill-corosync: + inject_script: ha_tools/fault_process_kill.bash + recovery_script: ha_tools/node/reboot_node.bash
\ No newline at end of file diff --git a/yardstick/benchmark/scenarios/availability/ha_tools/node/reboot_node.bash b/yardstick/benchmark/scenarios/availability/ha_tools/node/reboot_node.bash new file mode 100644 index 000000000..1ee8c9c2f --- /dev/null +++ b/yardstick/benchmark/scenarios/availability/ha_tools/node/reboot_node.bash @@ -0,0 +1,14 @@ +#!/bin/bash + +############################################################################## +# (c) OPNFV, Yin Kanglin and others. +# 14_ykl@tongji.edu.cn +# 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 +############################################################################## + +# reboot node + +reboot
\ No newline at end of file diff --git a/yardstick/benchmark/scenarios/availability/ha_tools/nova/get_server_floatingip.bash b/yardstick/benchmark/scenarios/availability/ha_tools/nova/get_server_floatingip.bash new file mode 100644 index 000000000..78dd27628 --- /dev/null +++ b/yardstick/benchmark/scenarios/availability/ha_tools/nova/get_server_floatingip.bash @@ -0,0 +1,23 @@ +#!/bin/bash + +############################################################################## +# (c) OPNFV, Yin Kanglin and others. +# 14_ykl@tongji.edu.cn +# 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 floating ip of a serer +# 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 | grep $1 | awk '{print $5}'
\ No newline at end of file diff --git a/yardstick/benchmark/scenarios/availability/ha_tools/nova/list_servers.bash b/yardstick/benchmark/scenarios/availability/ha_tools/nova/list_servers.bash new file mode 100644 index 000000000..0f67c021e --- /dev/null +++ b/yardstick/benchmark/scenarios/availability/ha_tools/nova/list_servers.bash @@ -0,0 +1,22 @@ +#!/bin/bash + +############################################################################## +# (c) OPNFV, Yin Kanglin and others. +# 14_ykl@tongji.edu.cn +# 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 +############################################################################## + +# list servers + +set -e + +if [ $OS_INSECURE ] && [ "$(echo $OS_INSECURE | tr '[:upper:]' '[:lower:]')" = "true" ]; then + SECURE="--insecure" +else + SECURE="" +fi + +openstack ${SECURE} server list
\ No newline at end of file diff --git a/yardstick/benchmark/scenarios/availability/ha_tools/pacemaker/get_resource_status.bash b/yardstick/benchmark/scenarios/availability/ha_tools/pacemaker/get_resource_status.bash new file mode 100644 index 000000000..68707cf4f --- /dev/null +++ b/yardstick/benchmark/scenarios/availability/ha_tools/pacemaker/get_resource_status.bash @@ -0,0 +1,14 @@ +#!/bin/bash + +############################################################################## +# (c) OPNFV, Yin Kanglin and others. +# 14_ykl@tongji.edu.cn +# 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 pacemaker resource status + +pcs resource show
\ No newline at end of file diff --git a/yardstick/benchmark/scenarios/availability/ha_tools/pacemaker/get_resource_status_host.bash b/yardstick/benchmark/scenarios/availability/ha_tools/pacemaker/get_resource_status_host.bash new file mode 100644 index 000000000..7a02ccf29 --- /dev/null +++ b/yardstick/benchmark/scenarios/availability/ha_tools/pacemaker/get_resource_status_host.bash @@ -0,0 +1,15 @@ +#!/bin/bash + +############################################################################## +# (c) OPNFV, Yin Kanglin and others. +# 14_ykl@tongji.edu.cn +# 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 pacemaker resource status of hosts +# parameter: $1 - resource name $2 status + +pcs resource show | grep $1 -A 3 | grep $2
\ No newline at end of file diff --git a/yardstick/benchmark/scenarios/availability/ha_tools/pacemaker/get_vip_host.bash b/yardstick/benchmark/scenarios/availability/ha_tools/pacemaker/get_vip_host.bash new file mode 100644 index 000000000..f4870fdae --- /dev/null +++ b/yardstick/benchmark/scenarios/availability/ha_tools/pacemaker/get_vip_host.bash @@ -0,0 +1,15 @@ +#!/bin/bash + +############################################################################## +# (c) OPNFV, Yin Kanglin and others. +# 14_ykl@tongji.edu.cn +# 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 vip host in pacemaker +# parameter: $1 - virtual ip name + +pcs resource show| grep -w $1 | awk '{print $4}'
\ No newline at end of file diff --git a/yardstick/benchmark/scenarios/availability/operation_conf.yaml b/yardstick/benchmark/scenarios/availability/operation_conf.yaml index 1c39385a9..dc5169196 100644 --- a/yardstick/benchmark/scenarios/availability/operation_conf.yaml +++ b/yardstick/benchmark/scenarios/availability/operation_conf.yaml @@ -25,4 +25,13 @@ swift-download-file: nova-create-flavor: action_script: ha_tools/nova/create_flavor.bash - rollback_script: ha_tools/nova/delete_flavor.bash
\ No newline at end of file + rollback_script: ha_tools/nova/delete_flavor.bash + +get-floatingip: + action_script: ha_tools/nova/get_server_floatingip.bash + rollback_script: ha_tools/nova/list_servers.bash + +get-vip-host: + action_script: ha_tools/pacemaker/get_vip_host.bash + rollback_script: ha_tools/pacemaker/get_resource_status.bash + diff --git a/yardstick/benchmark/scenarios/availability/result_checker_conf.yaml b/yardstick/benchmark/scenarios/availability/result_checker_conf.yaml index 0494a71a7..451cc0f11 100644 --- a/yardstick/benchmark/scenarios/availability/result_checker_conf.yaml +++ b/yardstick/benchmark/scenarios/availability/result_checker_conf.yaml @@ -18,4 +18,6 @@ service-checker: nova-instance-checker: verify_script: ha_tools/nova/show_instances.bash nova-flavor-checker: - verify_script: ha_tools/nova/show_flavors.bash
\ No newline at end of file + verify_script: ha_tools/nova/show_flavors.bash +pacemaker-resource-checker: + verify_script: ha_tools/pacemaker/get_resource_status_host.bash
\ No newline at end of file diff --git a/yardstick/benchmark/scenarios/availability/util.py b/yardstick/benchmark/scenarios/availability/util.py index 6fef622bd..d288fcbc1 100644 --- a/yardstick/benchmark/scenarios/availability/util.py +++ b/yardstick/benchmark/scenarios/availability/util.py @@ -51,6 +51,8 @@ def build_shell_command(param_config, remote=True, intermediate_variables=None): def read_stdout_item(stdout, key): + if key == "all": + return stdout for item in stdout.splitlines(): if key in item: attributes = item.split("|") diff --git a/yardstick/benchmark/scenarios/lib/create_keypair.py b/yardstick/benchmark/scenarios/lib/create_keypair.py index 5610de651..2185bfa5d 100644 --- a/yardstick/benchmark/scenarios/lib/create_keypair.py +++ b/yardstick/benchmark/scenarios/lib/create_keypair.py @@ -57,8 +57,10 @@ class CreateKeypair(base.Scenario): self.key_filename + ".pub") if keypair: + result.update({"keypair_create": 1}) LOG.info("Create keypair successful!") else: + result.update({"keypair_create": 0}) LOG.info("Create keypair failed!") try: keys = self.scenario_cfg.get('output', '').split() diff --git a/yardstick/benchmark/scenarios/lib/create_network.py b/yardstick/benchmark/scenarios/lib/create_network.py new file mode 100644 index 000000000..cffff132a --- /dev/null +++ b/yardstick/benchmark/scenarios/lib/create_network.py @@ -0,0 +1,64 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +from __future__ import print_function +from __future__ import absolute_import + +import logging + +from yardstick.benchmark.scenarios import base +import yardstick.common.openstack_utils as op_utils + +LOG = logging.getLogger(__name__) + + +class CreateNetwork(base.Scenario): + """Create an OpenStack network""" + + __scenario_type__ = "CreateNetwork" + + def __init__(self, scenario_cfg, context_cfg): + self.scenario_cfg = scenario_cfg + self.context_cfg = context_cfg + self.options = self.scenario_cfg['options'] + + self.openstack = self.options.get("openstack_paras", None) + + self.neutron_client = op_utils.get_neutron_client() + + self.setup_done = False + + def setup(self): + """scenario setup""" + + self.setup_done = True + + def run(self, result): + """execute the test""" + + if not self.setup_done: + self.setup() + + openstack_paras = {'network': self.openstack} + network_id = op_utils.create_neutron_net(self.neutron_client, + openstack_paras) + if network_id: + result.update({"network_create": 1}) + LOG.info("Create network successful!") + else: + result.update({"network_create": 0}) + LOG.error("Create network failed!") + + try: + keys = self.scenario_cfg.get('output', '').split() + except KeyError: + pass + else: + values = [network_id] + return self._push_to_outputs(keys, values) diff --git a/yardstick/benchmark/scenarios/lib/create_port.py b/yardstick/benchmark/scenarios/lib/create_port.py new file mode 100644 index 000000000..6a3a23a10 --- /dev/null +++ b/yardstick/benchmark/scenarios/lib/create_port.py @@ -0,0 +1,66 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +from __future__ import print_function +from __future__ import absolute_import + +import logging + +from yardstick.benchmark.scenarios import base +import yardstick.common.openstack_utils as op_utils + +LOG = logging.getLogger(__name__) + + +class CreatePort(base.Scenario): + """Create an OpenStack flavor""" + + __scenario_type__ = "CreatePort" + + def __init__(self, scenario_cfg, context_cfg): + self.scenario_cfg = scenario_cfg + self.context_cfg = context_cfg + self.options = self.scenario_cfg['options'] + + self.openstack = self.options.get("openstack_paras", None) + + self.neutron_client = op_utils.get_neutron_client() + + self.setup_done = False + + def setup(self): + """scenario setup""" + + self.setup_done = True + + def run(self, result): + """execute the test""" + + if not self.setup_done: + self.setup() + + openstack_paras = {'port': self.openstack} + port = self.neutron_client.create_port(openstack_paras) + + if port: + result.update({"Port_Create": 1}) + LOG.info("Create Port successful!") + else: + result.update({"Port_Create": 0}) + LOG.error("Create Port failed!") + + check_result = port['port']['id'] + + try: + keys = self.scenario_cfg.get('output', '').split() + except KeyError: + pass + else: + values = [check_result] + return self._push_to_outputs(keys, values) diff --git a/yardstick/benchmark/scenarios/lib/create_router.py b/yardstick/benchmark/scenarios/lib/create_router.py new file mode 100644 index 000000000..9aa57ebb2 --- /dev/null +++ b/yardstick/benchmark/scenarios/lib/create_router.py @@ -0,0 +1,66 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +from __future__ import print_function +from __future__ import absolute_import + +import logging + +from yardstick.benchmark.scenarios import base +import yardstick.common.openstack_utils as op_utils + +LOG = logging.getLogger(__name__) + + +class CreateRouter(base.Scenario): + """Create an OpenStack router""" + + __scenario_type__ = "CreateRouter" + + def __init__(self, scenario_cfg, context_cfg): + self.scenario_cfg = scenario_cfg + self.context_cfg = context_cfg + self.options = self.scenario_cfg['options'] + + self.openstack = self.options.get("openstack_paras", None) + + self.neutron_client = op_utils.get_neutron_client() + + self.setup_done = False + + def setup(self): + """scenario setup""" + + self.setup_done = True + + def run(self, result): + """execute the test""" + + if not self.setup_done: + self.setup() + + openstack_paras = {'router': self.openstack} + router_id = op_utils.create_neutron_router(self.neutron_client, + openstack_paras) + if router_id: + result.update({"network_create": 1}) + LOG.info("Create router successful!") + else: + result.update({"network_create": 0}) + LOG.error("Create router failed!") + + check_result = router_id + + try: + keys = self.scenario_cfg.get('output', '').split() + except KeyError: + pass + else: + values = [check_result] + return self._push_to_outputs(keys, values) diff --git a/yardstick/benchmark/scenarios/lib/create_sec_group.py b/yardstick/benchmark/scenarios/lib/create_sec_group.py new file mode 100644 index 000000000..3d1aec9e8 --- /dev/null +++ b/yardstick/benchmark/scenarios/lib/create_sec_group.py @@ -0,0 +1,65 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +from __future__ import print_function +from __future__ import absolute_import + +import logging + +from yardstick.benchmark.scenarios import base +import yardstick.common.openstack_utils as op_utils + +LOG = logging.getLogger(__name__) + + +class CreateSecgroup(base.Scenario): + """Create an OpenStack security group""" + + __scenario_type__ = "CreateSecgroup" + + def __init__(self, scenario_cfg, context_cfg): + self.scenario_cfg = scenario_cfg + self.context_cfg = context_cfg + self.options = self.scenario_cfg['options'] + + self.sg_name = self.options.get("sg_name", "yardstick_sec_group") + self.description = self.options.get("description", None) + self.neutron_client = op_utils.get_neutron_client() + + self.setup_done = False + + def setup(self): + """scenario setup""" + + self.setup_done = True + + def run(self, result): + """execute the test""" + + if not self.setup_done: + self.setup() + + sg_id = op_utils.create_security_group_full(self.neutron_client, + sg_name=self.sg_name, + sg_description=self.description) + + if sg_id: + result.update({"sg_create": 1}) + LOG.info("Create security group successful!") + else: + result.update({"sg_create": 0}) + LOG.error("Create security group failed!") + + try: + keys = self.scenario_cfg.get('output', '').split() + except KeyError: + pass + else: + values = [sg_id] + return self._push_to_outputs(keys, values) diff --git a/yardstick/benchmark/scenarios/lib/create_server.py b/yardstick/benchmark/scenarios/lib/create_server.py index 45c0bfde9..273b0045a 100644 --- a/yardstick/benchmark/scenarios/lib/create_server.py +++ b/yardstick/benchmark/scenarios/lib/create_server.py @@ -59,8 +59,10 @@ class CreateServer(base.Scenario): vm = op_utils.create_instance_and_wait_for_active(self.openstack) if vm: + result.update({"instance_create": 1}) LOG.info("Create server successful!") else: + result.update({"instance_create": 0}) LOG.error("Create server failed!") try: diff --git a/yardstick/benchmark/scenarios/lib/create_subnet.py b/yardstick/benchmark/scenarios/lib/create_subnet.py new file mode 100644 index 000000000..c34af8a9e --- /dev/null +++ b/yardstick/benchmark/scenarios/lib/create_subnet.py @@ -0,0 +1,66 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +from __future__ import print_function +from __future__ import absolute_import + +import logging + +from yardstick.benchmark.scenarios import base +import yardstick.common.openstack_utils as op_utils + +LOG = logging.getLogger(__name__) + + +class CreateSubnet(base.Scenario): + """Create an OpenStack flavor""" + + __scenario_type__ = "CreateSubnet" + + def __init__(self, scenario_cfg, context_cfg): + self.scenario_cfg = scenario_cfg + self.context_cfg = context_cfg + self.options = self.scenario_cfg['options'] + + self.openstack = self.options.get("openstack_paras", None) + + self.neutron_client = op_utils.get_neutron_client() + + self.setup_done = False + + def setup(self): + """scenario setup""" + + self.setup_done = True + + def run(self, result): + """execute the test""" + + if not self.setup_done: + self.setup() + + openstack_paras = {'subnets': [self.openstack]} + subnet_id = op_utils.create_neutron_subnet(self.neutron_client, + openstack_paras) + if subnet_id: + result.update({"subnet_create": 1}) + LOG.info("Create subnet successful!") + else: + result.update({"subnet_create": 0}) + LOG.error("Create subnet failed!") + + check_result = subnet_id + + try: + keys = self.scenario_cfg.get('output', '').split() + except KeyError: + pass + else: + values = [check_result] + return self._push_to_outputs(keys, values) diff --git a/yardstick/benchmark/scenarios/networking/vnf_generic.py b/yardstick/benchmark/scenarios/networking/vnf_generic.py index 55fdadea8..18a75d070 100644 --- a/yardstick/benchmark/scenarios/networking/vnf_generic.py +++ b/yardstick/benchmark/scenarios/networking/vnf_generic.py @@ -486,7 +486,6 @@ printf "%s/driver:" $1 ; basename $(readlink -s $1/device/driver); } \ for vnf in chain(traffic_runners, non_traffic_runners): LOG.info("Instantiating %s", vnf.name) vnf.instantiate(self.scenario_cfg, self.context_cfg) - for vnf in chain(traffic_runners, non_traffic_runners): LOG.info("Waiting for %s to instantiate", vnf.name) vnf.wait_for_instantiate() except RuntimeError: diff --git a/yardstick/common/openstack_utils.py b/yardstick/common/openstack_utils.py index 540d8d641..76acc9508 100644 --- a/yardstick/common/openstack_utils.py +++ b/yardstick/common/openstack_utils.py @@ -437,6 +437,36 @@ def get_port_id_by_ip(neutron_client, ip_address): # pragma: no cover 'fixed_ips') if j['ip_address'] == ip_address), None) +def create_neutron_net(neutron_client, json_body): # pragma: no cover + try: + network = neutron_client.create_network(body=json_body) + return network['network']['id'] + except Exception: + log.error("Error [create_neutron_net(neutron_client)]") + raise Exception("operation error") + return None + + +def create_neutron_subnet(neutron_client, json_body): # pragma: no cover + try: + subnet = neutron_client.create_subnet(body=json_body) + return subnet['subnets'][0]['id'] + except Exception: + log.error("Error [create_neutron_subnet") + raise Exception("operation error") + return None + + +def create_neutron_router(neutron_client, json_body): # pragma: no cover + try: + router = neutron_client.create_router(json_body) + return router['router']['id'] + except Exception: + log.error("Error [create_neutron_router(neutron_client)]") + raise Exception("operation error") + return None + + def create_floating_ip(neutron_client, extnet_id): # pragma: no cover props = {'floating_network_id': extnet_id} try: @@ -449,6 +479,120 @@ def create_floating_ip(neutron_client, extnet_id): # pragma: no cover return {'fip_addr': fip_addr, 'fip_id': fip_id} +def get_security_groups(neutron_client): # pragma: no cover + try: + security_groups = neutron_client.list_security_groups()[ + 'security_groups'] + return security_groups + except Exception: + log.error("Error [get_security_groups(neutron_client)]") + return None + + +def get_security_group_id(neutron_client, sg_name): # pragma: no cover + security_groups = get_security_groups(neutron_client) + id = '' + for sg in security_groups: + if sg['name'] == sg_name: + id = sg['id'] + break + return id + + +def create_security_group(neutron_client, sg_name, sg_description): # pragma: no cover + json_body = {'security_group': {'name': sg_name, + 'description': sg_description}} + try: + secgroup = neutron_client.create_security_group(json_body) + return secgroup['security_group'] + except Exception: + log.error("Error [create_security_group(neutron_client, '%s', " + "'%s')]" % (sg_name, sg_description)) + return None + + +def create_secgroup_rule(neutron_client, sg_id, direction, protocol, + port_range_min=None, port_range_max=None, + **json_body): # pragma: no cover + # We create a security group in 2 steps + # 1 - we check the format and set the json body accordingly + # 2 - we call neturon client to create the security group + + # Format check + json_body.update({'security_group_rule': {'direction': direction, + 'security_group_id': sg_id, 'protocol': protocol}}) + # parameters may be + # - both None => we do nothing + # - both Not None => we add them to the json description + # but one cannot be None is the other is not None + if (port_range_min is not None and port_range_max is not None): + # add port_range in json description + json_body['security_group_rule']['port_range_min'] = port_range_min + json_body['security_group_rule']['port_range_max'] = port_range_max + log.debug("Security_group format set (port range included)") + else: + # either both port range are set to None => do nothing + # or one is set but not the other => log it and return False + if port_range_min is None and port_range_max is None: + log.debug("Security_group format set (no port range mentioned)") + else: + log.error("Bad security group format." + "One of the port range is not properly set:" + "range min: {}," + "range max: {}".format(port_range_min, + port_range_max)) + return False + + # Create security group using neutron client + try: + neutron_client.create_security_group_rule(json_body) + return True + except Exception: + log.exception("Impossible to create_security_group_rule," + "security group rule probably already exists") + return False + + +def create_security_group_full(neutron_client, + sg_name, sg_description): # pragma: no cover + sg_id = get_security_group_id(neutron_client, sg_name) + if sg_id != '': + log.info("Using existing security group '%s'..." % sg_name) + else: + log.info("Creating security group '%s'..." % sg_name) + SECGROUP = create_security_group(neutron_client, + sg_name, + sg_description) + if not SECGROUP: + log.error("Failed to create the security group...") + return None + + sg_id = SECGROUP['id'] + + log.debug("Security group '%s' with ID=%s created successfully." + % (SECGROUP['name'], sg_id)) + + log.debug("Adding ICMP rules in security group '%s'..." + % sg_name) + if not create_secgroup_rule(neutron_client, sg_id, + 'ingress', 'icmp'): + log.error("Failed to create the security group rule...") + return None + + log.debug("Adding SSH rules in security group '%s'..." + % sg_name) + if not create_secgroup_rule( + neutron_client, sg_id, 'ingress', 'tcp', '22', '22'): + log.error("Failed to create the security group rule...") + return None + + if not create_secgroup_rule( + neutron_client, sg_id, 'egress', 'tcp', '22', '22'): + log.error("Failed to create the security group rule...") + return None + return sg_id + + # ********************************************* # GLANCE # ********************************************* diff --git a/yardstick/network_services/helpers/cpu.py b/yardstick/network_services/helpers/cpu.py index a5ba6c31e..8c21754ff 100644 --- a/yardstick/network_services/helpers/cpu.py +++ b/yardstick/network_services/helpers/cpu.py @@ -13,6 +13,9 @@ # limitations under the License. +import io + + class CpuSysCores(object): def __init__(self, connection=""): @@ -20,8 +23,9 @@ class CpuSysCores(object): self.connection = connection def _open_cpuinfo(self): - lines = [] - lines = self.connection.execute("cat /proc/cpuinfo")[1].split(u'\n') + cpuinfo = io.BytesIO() + self.connection.get_file_obj("/proc/cpuinfo", cpuinfo) + lines = cpuinfo.getvalue().decode('utf-8').splitlines() return lines def _get_core_details(self, lines): diff --git a/yardstick/ssh.py b/yardstick/ssh.py index 8ac3eaa3a..a024cf64a 100644 --- a/yardstick/ssh.py +++ b/yardstick/ssh.py @@ -423,6 +423,12 @@ class SSH(object): if mode is not None: sftp.chmod(remotepath, mode) + def get_file_obj(self, remotepath, file_obj): + client = self._get_client() + + with client.open_sftp() as sftp: + sftp.getfo(remotepath, file_obj) + class AutoConnectSSH(SSH): @@ -471,6 +477,10 @@ class AutoConnectSSH(SSH): self._connect() return super(AutoConnectSSH, self).put_file_obj(file_obj, remote_path, mode) + def get_file_obj(self, remote_path, file_obj): + self._connect() + return super(AutoConnectSSH, self).get_file_obj(remote_path, file_obj) + def provision_tool(self, tool_path, tool_file=None): self._connect() return super(AutoConnectSSH, self).provision_tool(tool_path, tool_file) |