diff options
author | Trevor Cooper <trevor.cooper@intel.com> | 2017-03-21 13:25:49 -0700 |
---|---|---|
committer | Trevor Cooper <trevor.cooper@intel.com> | 2017-03-21 13:25:49 -0700 |
commit | 32a5263216d79ad34041dca55357278f092bb931 (patch) | |
tree | e3bf10ba8190ad93d2b114c1903cc43e2dfbf6b6 /docs/testing/user/userguide/teststeps.rst | |
parent | 59668b1aa68da507335ef351619d9f50019df762 (diff) |
Moved doc files to testing document structure testing/user ... testing/developer and modified doc index to match dir structure
Change-Id: I4b1a535808a48773505fa7874c61707cd349fced
Signed-off-by: Trevor Cooper <trevor.cooper@intel.com>
Diffstat (limited to 'docs/testing/user/userguide/teststeps.rst')
-rw-r--r-- | docs/testing/user/userguide/teststeps.rst | 667 |
1 files changed, 667 insertions, 0 deletions
diff --git a/docs/testing/user/userguide/teststeps.rst b/docs/testing/user/userguide/teststeps.rst new file mode 100644 index 00000000..870c3d80 --- /dev/null +++ b/docs/testing/user/userguide/teststeps.rst @@ -0,0 +1,667 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +.. (c) OPNFV, Intel Corporation, AT&T and others. + +.. _step-driven-tests: + +Step driven tests +================= + +In general, test scenarios are defined by a ``deployment`` used in the particular +test case definition. The chosen deployment scenario will take care of the vSwitch +configuration, deployment of VNFs and it can also affect configuration of a traffic +generator. In order to allow a more flexible way of testcase scripting, VSPERF supports +a detailed step driven testcase definition. It can be used to configure and +program vSwitch, deploy and terminate VNFs, execute a traffic generator, +modify a VSPERF configuration, execute external commands, etc. + +Execution of step driven tests is done on a step by step work flow starting +with step 0 as defined inside the test case. Each step of the test increments +the step number by one which is indicated in the log. + +.. code-block:: console + + (testcases.integration) - Step 0 'vswitch add_vport ['br0']' start + +Step driven tests can be used for both performance and integration testing. +In case of integration test, each step in the test case is validated. If a step +does not pass validation the test will fail and terminate. The test will continue +until a failure is detected or all steps pass. A csv report file is generated after +a test completes with an OK or FAIL result. + +In case of performance test, the validation of steps is not performed and +standard output files with results from traffic generator and underlying OS +details are generated by vsperf. + +Step driven testcases can be used in two different ways: + + # description of full testcase - in this case ``clean`` deployment is used + to indicate that vsperf should neither configure vSwitch nor deploy any VNF. + Test shall perform all required vSwitch configuration and programming and + deploy required number of VNFs. + + # modification of existing deployment - in this case, any of supported + deployments can be used to perform initial vSwitch configuration and + deployment of VNFs. Additional actions defined by TestSteps can be used + to alter vSwitch configuration or deploy additional VNFs. After the last + step is processed, the test execution will continue with traffic execution. + +Test objects and their functions +-------------------------------- + +Every test step can call a function of one of the supported test objects. The list +of supported objects and their most common functions follows: + + * ``vswitch`` - provides functions for vSwitch configuration + + List of supported functions: + + * ``add_switch br_name`` - creates a new switch (bridge) with given ``br_name`` + * ``del_switch br_name`` - deletes switch (bridge) with given ``br_name`` + * ``add_phy_port br_name`` - adds a physical port into bridge specified by ``br_name`` + * ``add_vport br_name`` - adds a virtual port into bridge specified by ``br_name`` + * ``del_port br_name port_name`` - removes physical or virtual port specified by + ``port_name`` from bridge ``br_name`` + * ``add_flow br_name flow`` - adds flow specified by ``flow`` dictionary into + the bridge ``br_name``; Content of flow dictionary will be passed to the vSwitch. + In case of Open vSwitch it will be passed to the ``ovs-ofctl add-flow`` command. + Please see Open vSwitch documentation for the list of supported flow parameters. + * ``del_flow br_name [flow]`` - deletes flow specified by ``flow`` dictionary from + bridge ``br_name``; In case that optional parameter ``flow`` is not specified + or set to an empty dictionary ``{}``, then all flows from bridge ``br_name`` + will be deleted. + * ``dump_flows br_name`` - dumps all flows from bridge specified by ``br_name`` + * ``enable_stp br_name`` - enables Spanning Tree Protocol for bridge ``br_name`` + * ``disable_stp br_name`` - disables Spanning Tree Protocol for bridge ``br_name`` + * ``enable_rstp br_name`` - enables Rapid Spanning Tree Protocol for bridge ``br_name`` + * ``disable_rstp br_name`` - disables Rapid Spanning Tree Protocol for bridge ``br_name`` + + Examples: + + .. code-block:: python + + ['vswitch', 'add_switch', 'int_br0'] + + ['vswitch', 'del_switch', 'int_br0'] + + ['vswitch', 'add_phy_port', 'int_br0'] + + ['vswitch', 'del_port', 'int_br0', '#STEP[2][0]'] + + ['vswitch', 'add_flow', 'int_br0', {'in_port': '1', 'actions': ['output:2'], + 'idle_timeout': '0'}], + + ['vswitch', 'enable_rstp', 'int_br0'] + + * ``vnf[ID]`` - provides functions for deployment and termination of VNFs; Optional + alfanumerical ``ID`` is used for VNF identification in case that testcase + deploys multiple VNFs. + + List of supported functions: + + * ``start`` - starts a VNF based on VSPERF configuration + * ``stop`` - gracefully terminates given VNF + + Examples: + + .. code-block:: python + + ['vnf1', 'start'] + ['vnf2', 'start'] + ['vnf2', 'stop'] + ['vnf1', 'stop'] + + * ``trafficgen`` - triggers traffic generation + + List of supported functions: + + * ``send_traffic traffic`` - starts a traffic based on the vsperf configuration + and given ``traffic`` dictionary. More details about ``traffic`` dictionary + and its possible values are available at :ref:`Traffic Generator Integration Guide + <step-5-supported-traffic-types>` + + Examples: + + .. code-block:: python + + ['trafficgen', 'send_traffic', {'traffic_type' : 'rfc2544_throughput'}] + + ['trafficgen', 'send_traffic', {'traffic_type' : 'rfc2544_back2back', 'bidir' : 'True'}] + + * ``settings`` - reads or modifies VSPERF configuration + + List of supported functions: + + * ``getValue param`` - returns value of given ``param`` + * ``setValue param value`` - sets value of ``param`` to given ``value`` + + Examples: + + .. code-block:: python + + ['settings', 'getValue', 'TOOLS'] + + ['settings', 'setValue', 'GUEST_USERNAME', ['root']] + + * ``namespace`` - creates or modifies network namespaces + + List of supported functions: + + * ``create_namespace name`` - creates new namespace with given ``name`` + * ``delete_namespace name`` - deletes namespace specified by its ``name`` + * ``assign_port_to_namespace port name [port_up]`` - assigns NIC specified by ``port`` + into given namespace ``name``; If optional parameter ``port_up`` is set to ``True``, + then port will be brought up. + * ``add_ip_to_namespace_eth port name addr cidr`` - assigns an IP address ``addr``/``cidr`` + to the NIC specified by ``port`` within namespace ``name`` + * ``reset_port_to_root port name`` - returns given ``port`` from namespace ``name`` back + to the root namespace + + Examples: + + .. code-block:: python + + ['namespace', 'create_namespace', 'testns'] + + ['namespace', 'assign_port_to_namespace', 'eth0', 'testns'] + + * ``veth`` - manipulates with eth and veth devices + + List of supported functions: + + * ``add_veth_port port peer_port`` - adds a pair of veth ports named ``port`` and + ``peer_port`` + * ``del_veth_port port peer_port`` - deletes a veth port pair specified by ``port`` + and ``peer_port`` + * ``bring_up_eth_port eth_port [namespace]`` - brings up ``eth_port`` in (optional) + ``namespace`` + + Examples: + + .. code-block:: python + + ['veth', 'add_veth_port', 'veth', 'veth1'] + + ['veth', 'bring_up_eth_port', 'eth1'] + + * ``tools`` - provides a set of helper functions + + List of supported functions: + + * ``Assert condition`` - evaluates given ``condition`` and raises ``AssertionError`` + in case that condition is not ``True`` + * ``Eval expression`` - evaluates given expression as a python code and returns + its result + * ``Exec command [regex]`` - executes a shell command and filters its output by + (optional) regular expression + + Examples: + + .. code-block:: python + + ['tools', 'exec', 'numactl -H', 'available: ([0-9]+)'] + ['tools', 'assert', '#STEP[-1][0]>1'] + + * ``wait`` - is used for test case interruption. This object doesn't have + any functions. Once reached, vsperf will pause test execution and waits + for press of ``Enter key``. It can be used during testcase design + for debugging purposes. + + Examples: + + .. code-block:: python + + ['wait'] + +Test Macros +----------- + +Test profiles can include macros as part of the test step. Each step in the +profile may return a value such as a port name. Recall macros use #STEP to +indicate the recalled value inside the return structure. If the method the +test step calls returns a value it can be later recalled, for example: + +.. code-block:: python + + { + "Name": "vswitch_add_del_vport", + "Deployment": "clean", + "Description": "vSwitch - add and delete virtual port", + "TestSteps": [ + ['vswitch', 'add_switch', 'int_br0'], # STEP 0 + ['vswitch', 'add_vport', 'int_br0'], # STEP 1 + ['vswitch', 'del_port', 'int_br0', '#STEP[1][0]'], # STEP 2 + ['vswitch', 'del_switch', 'int_br0'], # STEP 3 + ] + } + +This test profile uses the vswitch add_vport method which returns a string +value of the port added. This is later called by the del_port method using the +name from step 1. + +It is also possible to use negative indexes in step macros. In that case +``#STEP[-1]`` will refer to the result from previous step, ``#STEP[-2]`` +will refer to result of step called before previous step, etc. It means, +that you could change ``STEP 2`` from previous example to achieve the same +functionality: + +.. code-block:: python + + ['vswitch', 'del_port', 'int_br0', '#STEP[-1][0]'], # STEP 2 + +Also commonly used steps can be created as a separate profile. + +.. code-block:: python + + STEP_VSWITCH_PVP_INIT = [ + ['vswitch', 'add_switch', 'int_br0'], # STEP 0 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 1 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 2 + ['vswitch', 'add_vport', 'int_br0'], # STEP 3 + ['vswitch', 'add_vport', 'int_br0'], # STEP 4 + ] + +This profile can then be used inside other testcases + +.. code-block:: python + + { + "Name": "vswitch_pvp", + "Deployment": "clean", + "Description": "vSwitch - configure switch and one vnf", + "TestSteps": STEP_VSWITCH_PVP_INIT + + [ + ['vnf', 'start'], + ['vnf', 'stop'], + ] + + STEP_VSWITCH_PVP_FINIT + } + +HelloWorld and other basic Testcases +------------------------------------ + +The following examples are for demonstration purposes. +You can run them by copying and pasting into the +conf/integration/01_testcases.conf file. +A command-line instruction is shown at the end of each +example. + +HelloWorld +^^^^^^^^^^ + +The first example is a HelloWorld testcase. +It simply creates a bridge with 2 physical ports, then sets up a flow to drop +incoming packets from the port that was instantiated at the STEP #1. +There's no interaction with the traffic generator. +Then the flow, the 2 ports and the bridge are deleted. +'add_phy_port' method creates a 'dpdk' type interface that will manage the +physical port. The string value returned is the port name that will be referred +by 'del_port' later on. + +.. code-block:: python + + { + "Name": "HelloWorld", + "Description": "My first testcase", + "Deployment": "clean", + "TestSteps": [ + ['vswitch', 'add_switch', 'int_br0'], # STEP 0 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 1 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 2 + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', \ + 'actions': ['drop'], 'idle_timeout': '0'}], + ['vswitch', 'del_flow', 'int_br0'], + ['vswitch', 'del_port', 'int_br0', '#STEP[1][0]'], + ['vswitch', 'del_port', 'int_br0', '#STEP[2][0]'], + ['vswitch', 'del_switch', 'int_br0'], + ] + + }, + +To run HelloWorld test: + + .. code-block:: console + + ./vsperf --conf-file user_settings.py --integration HelloWorld + +Specify a Flow by the IP address +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The next example shows how to explicitly set up a flow by specifying a +destination IP address. +All packets received from the port created at STEP #1 that have a destination +IP address = 90.90.90.90 will be forwarded to the port created at the STEP #2. + +.. code-block:: python + + { + "Name": "p2p_rule_l3da", + "Description": "Phy2Phy with rule on L3 Dest Addr", + "Deployment": "clean", + "biDirectional": "False", + "TestSteps": [ + ['vswitch', 'add_switch', 'int_br0'], # STEP 0 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 1 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 2 + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', \ + 'dl_type': '0x0800', 'nw_dst': '90.90.90.90', \ + 'actions': ['output:#STEP[2][1]'], 'idle_timeout': '0'}], + ['trafficgen', 'send_traffic', \ + {'traffic_type' : 'rfc2544_continuous'}], + ['vswitch', 'dump_flows', 'int_br0'], # STEP 5 + ['vswitch', 'del_flow', 'int_br0'], # STEP 7 == del-flows + ['vswitch', 'del_port', 'int_br0', '#STEP[1][0]'], + ['vswitch', 'del_port', 'int_br0', '#STEP[2][0]'], + ['vswitch', 'del_switch', 'int_br0'], + ] + }, + +To run the test: + + .. code-block:: console + + ./vsperf --conf-file user_settings.py --integration p2p_rule_l3da + +Multistream feature +^^^^^^^^^^^^^^^^^^^ + +The next testcase uses the multistream feature. +The traffic generator will send packets with different UDP ports. +That is accomplished by using "Stream Type" and "MultiStream" keywords. +4 different flows are set to forward all incoming packets. + +.. code-block:: python + + { + "Name": "multistream_l4", + "Description": "Multistream on UDP ports", + "Deployment": "clean", + "Parameters": { + 'TRAFFIC' : { + "multistream": 4, + "stream_type": "L4", + }, + }, + "TestSteps": [ + ['vswitch', 'add_switch', 'int_br0'], # STEP 0 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 1 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 2 + # Setup Flows + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', \ + 'dl_type': '0x0800', 'nw_proto': '17', 'udp_dst': '0', \ + 'actions': ['output:#STEP[2][1]'], 'idle_timeout': '0'}], + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', \ + 'dl_type': '0x0800', 'nw_proto': '17', 'udp_dst': '1', \ + 'actions': ['output:#STEP[2][1]'], 'idle_timeout': '0'}], + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', \ + 'dl_type': '0x0800', 'nw_proto': '17', 'udp_dst': '2', \ + 'actions': ['output:#STEP[2][1]'], 'idle_timeout': '0'}], + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', \ + 'dl_type': '0x0800', 'nw_proto': '17', 'udp_dst': '3', \ + 'actions': ['output:#STEP[2][1]'], 'idle_timeout': '0'}], + # Send mono-dir traffic + ['trafficgen', 'send_traffic', \ + {'traffic_type' : 'rfc2544_continuous', \ + 'bidir' : 'False'}], + # Clean up + ['vswitch', 'del_flow', 'int_br0'], + ['vswitch', 'del_port', 'int_br0', '#STEP[1][0]'], + ['vswitch', 'del_port', 'int_br0', '#STEP[2][0]'], + ['vswitch', 'del_switch', 'int_br0'], + ] + }, + +To run the test: + + .. code-block:: console + + ./vsperf --conf-file user_settings.py --integration multistream_l4 + +PVP with a VM Replacement +^^^^^^^^^^^^^^^^^^^^^^^^^ + +This example launches a 1st VM in a PVP topology, then the VM is replaced +by another VM. +When VNF setup parameter in ./conf/04_vnf.conf is "QemuDpdkVhostUser" +'add_vport' method creates a 'dpdkvhostuser' type port to connect a VM. + +.. code-block:: python + + { + "Name": "ex_replace_vm", + "Description": "PVP with VM replacement", + "Deployment": "clean", + "TestSteps": [ + ['vswitch', 'add_switch', 'int_br0'], # STEP 0 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 1 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 2 + ['vswitch', 'add_vport', 'int_br0'], # STEP 3 vm1 + ['vswitch', 'add_vport', 'int_br0'], # STEP 4 + + # Setup Flows + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', \ + 'actions': ['output:#STEP[3][1]'], 'idle_timeout': '0'}], + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[4][1]', \ + 'actions': ['output:#STEP[2][1]'], 'idle_timeout': '0'}], + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[2][1]', \ + 'actions': ['output:#STEP[4][1]'], 'idle_timeout': '0'}], + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[3][1]', \ + 'actions': ['output:#STEP[1][1]'], 'idle_timeout': '0'}], + + # Start VM 1 + ['vnf1', 'start'], + # Now we want to replace VM 1 with another VM + ['vnf1', 'stop'], + + ['vswitch', 'add_vport', 'int_br0'], # STEP 11 vm2 + ['vswitch', 'add_vport', 'int_br0'], # STEP 12 + ['vswitch', 'del_flow', 'int_br0'], + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', \ + 'actions': ['output:#STEP[11][1]'], 'idle_timeout': '0'}], + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[12][1]', \ + 'actions': ['output:#STEP[2][1]'], 'idle_timeout': '0'}], + + # Start VM 2 + ['vnf2', 'start'], + ['vnf2', 'stop'], + ['vswitch', 'dump_flows', 'int_br0'], + + # Clean up + ['vswitch', 'del_flow', 'int_br0'], + ['vswitch', 'del_port', 'int_br0', '#STEP[1][0]'], + ['vswitch', 'del_port', 'int_br0', '#STEP[2][0]'], + ['vswitch', 'del_port', 'int_br0', '#STEP[3][0]'], # vm1 + ['vswitch', 'del_port', 'int_br0', '#STEP[4][0]'], + ['vswitch', 'del_port', 'int_br0', '#STEP[11][0]'], # vm2 + ['vswitch', 'del_port', 'int_br0', '#STEP[12][0]'], + ['vswitch', 'del_switch', 'int_br0'], + ] + }, + +To run the test: + + .. code-block:: console + + ./vsperf --conf-file user_settings.py --integration ex_replace_vm + +VM with a Linux bridge +^^^^^^^^^^^^^^^^^^^^^^ + +This example setups a PVP topology and routes traffic to the VM based on +the destination IP address. A command-line parameter is used to select a Linux +bridge as a guest loopback application. It is also possible to select a guest +loopback application by a configuration option ``GUEST_LOOPBACK``. + +.. code-block:: python + + { + "Name": "ex_pvp_rule_l3da", + "Description": "PVP with flow on L3 Dest Addr", + "Deployment": "clean", + "TestSteps": [ + ['vswitch', 'add_switch', 'int_br0'], # STEP 0 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 1 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 2 + ['vswitch', 'add_vport', 'int_br0'], # STEP 3 vm1 + ['vswitch', 'add_vport', 'int_br0'], # STEP 4 + # Setup Flows + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', \ + 'dl_type': '0x0800', 'nw_dst': '90.90.90.90', \ + 'actions': ['output:#STEP[3][1]'], 'idle_timeout': '0'}], + # Each pkt from the VM is forwarded to the 2nd dpdk port + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[4][1]', \ + 'actions': ['output:#STEP[2][1]'], 'idle_timeout': '0'}], + # Start VMs + ['vnf1', 'start'], + ['trafficgen', 'send_traffic', \ + {'traffic_type' : 'rfc2544_continuous', \ + 'bidir' : 'False'}], + ['vnf1', 'stop'], + # Clean up + ['vswitch', 'dump_flows', 'int_br0'], # STEP 10 + ['vswitch', 'del_flow', 'int_br0'], # STEP 11 + ['vswitch', 'del_port', 'int_br0', '#STEP[1][0]'], + ['vswitch', 'del_port', 'int_br0', '#STEP[2][0]'], + ['vswitch', 'del_port', 'int_br0', '#STEP[3][0]'], # vm1 ports + ['vswitch', 'del_port', 'int_br0', '#STEP[4][0]'], + ['vswitch', 'del_switch', 'int_br0'], + ] + }, + +To run the test: + + .. code-block:: console + + ./vsperf --conf-file user_settings.py --test-params \ + "GUEST_LOOPBACK=['linux_bridge']" --integration ex_pvp_rule_l3da + +Forward packets based on UDP port +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This examples launches 2 VMs connected in parallel. +Incoming packets will be forwarded to one specific VM depending on the +destination UDP port. + +.. code-block:: python + + { + "Name": "ex_2pvp_rule_l4dp", + "Description": "2 PVP with flows on L4 Dest Port", + "Deployment": "clean", + "Parameters": { + 'TRAFFIC' : { + "multistream": 2, + "stream_type": "L4", + }, + }, + "TestSteps": [ + ['vswitch', 'add_switch', 'int_br0'], # STEP 0 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 1 + ['vswitch', 'add_phy_port', 'int_br0'], # STEP 2 + ['vswitch', 'add_vport', 'int_br0'], # STEP 3 vm1 + ['vswitch', 'add_vport', 'int_br0'], # STEP 4 + ['vswitch', 'add_vport', 'int_br0'], # STEP 5 vm2 + ['vswitch', 'add_vport', 'int_br0'], # STEP 6 + # Setup Flows to reply ICMPv6 and similar packets, so to + # avoid flooding internal port with their re-transmissions + ['vswitch', 'add_flow', 'int_br0', \ + {'priority': '1', 'dl_src': '00:00:00:00:00:01', \ + 'actions': ['output:#STEP[3][1]'], 'idle_timeout': '0'}], + ['vswitch', 'add_flow', 'int_br0', \ + {'priority': '1', 'dl_src': '00:00:00:00:00:02', \ + 'actions': ['output:#STEP[4][1]'], 'idle_timeout': '0'}], + ['vswitch', 'add_flow', 'int_br0', \ + {'priority': '1', 'dl_src': '00:00:00:00:00:03', \ + 'actions': ['output:#STEP[5][1]'], 'idle_timeout': '0'}], + ['vswitch', 'add_flow', 'int_br0', \ + {'priority': '1', 'dl_src': '00:00:00:00:00:04', \ + 'actions': ['output:#STEP[6][1]'], 'idle_timeout': '0'}], + # Forward UDP packets depending on dest port + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', \ + 'dl_type': '0x0800', 'nw_proto': '17', 'udp_dst': '0', \ + 'actions': ['output:#STEP[3][1]'], 'idle_timeout': '0'}], + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[1][1]', \ + 'dl_type': '0x0800', 'nw_proto': '17', 'udp_dst': '1', \ + 'actions': ['output:#STEP[5][1]'], 'idle_timeout': '0'}], + # Send VM output to phy port #2 + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[4][1]', \ + 'actions': ['output:#STEP[2][1]'], 'idle_timeout': '0'}], + ['vswitch', 'add_flow', 'int_br0', {'in_port': '#STEP[6][1]', \ + 'actions': ['output:#STEP[2][1]'], 'idle_timeout': '0'}], + # Start VMs + ['vnf1', 'start'], # STEP 16 + ['vnf2', 'start'], # STEP 17 + ['trafficgen', 'send_traffic', \ + {'traffic_type' : 'rfc2544_continuous', \ + 'bidir' : 'False'}], + ['vnf1', 'stop'], + ['vnf2', 'stop'], + ['vswitch', 'dump_flows', 'int_br0'], + # Clean up + ['vswitch', 'del_flow', 'int_br0'], + ['vswitch', 'del_port', 'int_br0', '#STEP[1][0]'], + ['vswitch', 'del_port', 'int_br0', '#STEP[2][0]'], + ['vswitch', 'del_port', 'int_br0', '#STEP[3][0]'], # vm1 ports + ['vswitch', 'del_port', 'int_br0', '#STEP[4][0]'], + ['vswitch', 'del_port', 'int_br0', '#STEP[5][0]'], # vm2 ports + ['vswitch', 'del_port', 'int_br0', '#STEP[6][0]'], + ['vswitch', 'del_switch', 'int_br0'], + ] + }, + +To run the test: + + .. code-block:: console + + ./vsperf --conf-file user_settings.py --integration ex_2pvp_rule_l4dp + +Modification of existing PVVP deployment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This is an example of modification of a standard deployment scenario with additional TestSteps. +Standard PVVP scenario is used to configure a vSwitch and to deploy two VNFs connected +in series. Additional TestSteps will deploy a 3rd VNF and connect it in parallel to +already configured VNFs. Traffic generator is instructed (by Multistream feature) to send +two separate traffic streams. One stream will be sent to the standalone VNF and second +to two chained VNFs. + +In case, that test is defined as a performance test, then traffic results will be collected +and available in both csv and rst report files. + +.. code-block:: python + + { + "Name": "pvvp_pvp_cont", + "Deployment": "pvvp", + "Description": "PVVP and PVP in parallel with Continuous Stream", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_continuous", + "multistream": 2, + }, + }, + "TestSteps": [ + ['vswitch', 'add_vport', 'br0'], + ['vswitch', 'add_vport', 'br0'], + # priority must be higher than default 32768, otherwise flows won't match + ['vswitch', 'add_flow', 'br0', + {'in_port': '1', 'actions': ['output:#STEP[-2][1]'], 'idle_timeout': '0', 'dl_type':'0x0800', + 'nw_proto':'17', 'tp_dst':'0', 'priority': '33000'}], + ['vswitch', 'add_flow', 'br0', + {'in_port': '2', 'actions': ['output:#STEP[-2][1]'], 'idle_timeout': '0', 'dl_type':'0x0800', + 'nw_proto':'17', 'tp_dst':'0', 'priority': '33000'}], + ['vswitch', 'add_flow', 'br0', {'in_port': '#STEP[-4][1]', 'actions': ['output:1'], + 'idle_timeout': '0'}], + ['vswitch', 'add_flow', 'br0', {'in_port': '#STEP[-4][1]', 'actions': ['output:2'], + 'idle_timeout': '0'}], + ['vswitch', 'dump_flows', 'br0'], + ['vnf1', 'start'], + ] + }, + +To run the test: + + .. code-block:: console + + ./vsperf --conf-file user_settings.py pvvp_pvp_cont + |