Switched multi-threads testing from iperf3 to iperf

Switched multi-threads testing from iperf3 to iperf because the
iperf3 was not designed for the multiple threads, see [1] and [2].
So, iperf (v2) will be used for measuring tests with -P option.

Made the number of threads as an configurable option (10 by default).

* installing iperf package
* allowing 5001 port
* starting iperf as well as iperf3 at VMs
* added 'multiple_threads_number' option (10 by default)
* added details which tool was used (iperf3 or iperf) in the final table
* changed the default image from Ubuntu18 to Ubuntu20

[1] https: //fasterdata.es.net/performance-testing/network-troubleshooting-tools/iperf/multi-stream-iperf3/
[2] https: //github.com/esnet/iperf/issues/289

Related-PROD: PROD-36943
Change-Id: I39d2c44723344c87836bf7b5fa02b546a08f2ca5
diff --git a/README.md b/README.md
index 36e7dc0..51de507 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@
 | flavor_ram | 1536 | To define RAM allocation for specific flavor, MB |
 | flavor_vcpus | 1 | To define a count of vCPU for flavor |
 | flavor_disk | 5 | To define a count of disks on flavor, GB |
-| image_name | Ubuntu-18.04 | Cloud Ubuntu image to create VMs |
+| image_name | cvp.ubuntu.2004 | Cloud Ubuntu image to create VMs. Use 20.04 image in case internet_at_vms=false since the offline packages are set for Ubuntu 20.04. You can use any other Ubuntu image in case internet_at_vms=true. |
 | CMP_HOSTS | "" | Pair of compute hosts to create VMs at different hosts. By default, some random pair from nova compute list will be selected. To set some pair, set _CMP_HOSTS: ["cmp001", "cmp002"]_ in _global_config.yaml_ file, or export CMP_HOSTS="cmp001,cmp002". | 
 | skipped_nodes | "" | Skip some compute hosts, so they are not selected at CMP_HOSTS pair. To set some nodes to skip, set _skipped_nodes: ["cmp003"]_ in _global_config.yaml_ file, or export skipped_nodes="cmp003".|
 | nova_timeout | 300 | Timeout to VM to be ACTIVE, seconds. |
diff --git a/fixtures/base.py b/fixtures/base.py
index 2ecfc21..630e69f 100644
--- a/fixtures/base.py
+++ b/fixtures/base.py
@@ -37,7 +37,7 @@
     os_actions = os_client.OSCliActions(openstack_clients)
     os_resource = {}
     config = utils.get_configuration()
-    image_name = config.get('image_name', 'Ubuntu-18.04')
+    image_name = config.get('image_name', 'cvp.ubuntu.2004')
     flavor_name = config.get('flavor_name', 'spt-test')
     flavor_ram = config.get('flavor_ram', 1536)
     flavor_vcpus = config.get('flavor_vcpus', 1)
diff --git a/global_config.yaml b/global_config.yaml
index 025bd60..5bdb6f0 100644
--- a/global_config.yaml
+++ b/global_config.yaml
@@ -4,7 +4,7 @@
 
 # parameters for vm2vm test
 CMP_HOSTS: []
-image_name: "Ubuntu-18.04"
+image_name: "cvp.ubuntu.2004" # Use Ubuntu 20.04 LTS image
 flavor_name: 'spt-test'
 flavor_ram: 1536
 flavor_vcpus: 1
@@ -16,5 +16,6 @@
 internet_at_vms: 'true' # whether Internet is present at OpenStack VMs and iperf can be installed with apt
 iperf_deb_package_dir_path: '/opt/packages/'
 iperf_time: 60 # time in seconds to transmit for (iperf -t option)
+multiple_threads_number: 10
 ssh_timeout: 500
 skipped_nodes: []
diff --git a/tests/test_vm2vm.py b/tests/test_vm2vm.py
index 4367ee8..9c6d107 100644
--- a/tests/test_vm2vm.py
+++ b/tests/test_vm2vm.py
@@ -21,7 +21,8 @@
     3. Connect to each VM via SSH and install iperf3
     4. Measure VM to VM on same node via Private IP, 1 thread
     5. Measure VM to VM on different HW nodes via Private IP, 1 thread
-    6. Measure VM to VM on different HW nodes via Private IP, 10 threads
+    6. Measure VM to VM on different HW nodes via Private IP, multiple threads
+       (10 by default)
     7. Measure VM to VM on different HW nodes via Floating IP, 1 thread
     8. Measure VM to VM on different HW nodes, each VM is in separate network,
        the networks are connected using Router via Private IP, 1 thread
@@ -33,7 +34,8 @@
     iperf_time = int(config.get('iperf_time', 60))
     private_key = os_resources['keypair'].private_key
     ssh_timeout = int(config.get('ssh_timeout', 500))
-    result_table = Texttable()
+    threads = int(config.get('multiple_threads_number', 10))
+    result_table = Texttable(max_width=120)
 
     try:
         zone1 = [service.zone for service in
@@ -115,7 +117,7 @@
         res1 = (b" ".join(result1.split()[-4:-2:])).decode('utf-8')
         logger.info("Result #1 is {}".format(res1))
         table_rows.append(['VM to VM in same tenant on same node via '
-                           'Private IP, 1 thread',
+                           'Private IP, 1 thread; iperf3',
                            "{}".format(pair[0]),
                            "{}".format(pair[0]),
                            "{}, {}".format(mtus[0], mtus[1]),
@@ -130,7 +132,7 @@
         res2 = (b" ".join(result2.split()[-4:-2:])).decode('utf-8')
         logger.info("Result #2 is {}".format(res2))
         table_rows.append(['VM to VM in same tenant on different HW nodes '
-                           'via Private IP, 1 thread',
+                           'via Private IP, 1 thread; iperf3',
                            "{}".format(pair[0]),
                            "{}".format(pair[1]),
                            "{}, {}".format(mtus[0], mtus[2]),
@@ -138,20 +140,21 @@
 
         # Do iperf3 measurement #3
         logger.info("Doing 'VM to VM in same tenant on different HW nodes "
-                    "via Private IP, 10 threads' measurement...")
+                    "via Private IP, {} threads' measurement..."
+                    "".format(threads))
         result3 = transport1.exec_command(
-            'iperf3 -c {} -P 10 -t {} | grep sender | tail -n 1'.format(
-                vm_info[2]['private_address'], iperf_time))
-        res3 = (b" ".join(result3.split()[-4:-2:])).decode('utf-8')
+            'iperf -c {} -P {} -t {} | tail -n 1'.format(
+                vm_info[2]['private_address'], threads, iperf_time))
+        res3 = (b" ".join(result3.split()[-2::])).decode('utf-8')
         logger.info("Result #3 is {}".format(res3))
         table_rows.append(['VM to VM in same tenant on different HW nodes '
-                           'via Private IP, 10 threads',
+                           'via Private IP, {} threads; iperf (v2)'.format(threads),
                            "{}".format(pair[0]),
                            "{}".format(pair[1]),
                            "{}, {}".format(mtus[0], mtus[2]),
                            "{}".format(res3)])
 
-        # Do iperf3 measurement #4
+        # Do iperf (v2) measurement #4
         logger.info("Doing 'VM to VM in same tenant via Floating IP and VMs "
                     "are on different nodes, 1 thread' measurement...")
         result4 = transport1.exec_command(
@@ -160,7 +163,7 @@
         res4 = (b" ".join(result4.split()[-4:-2:])).decode('utf-8')
         logger.info("Result #4 is {}".format(res4))
         table_rows.append(['VM to VM in same tenant via Floating IP and VMs '
-                           'are on different nodes, 1 thread',
+                           'are on different nodes, 1 thread; iperf3',
                            "{}".format(pair[0]),
                            "{}".format(pair[1]),
                            "{}, {}".format(mtus[0], mtus[2]),
@@ -178,7 +181,8 @@
         logger.info("Result #5 is {}".format(res5))
         table_rows.append(['VM to VM in same tenant, different HW nodes and '
                            'each VM is connected to separate network which are'
-                           ' connected using Router via Private IP, 1 thread',
+                           ' connected using Router via Private IP, 1 thread; '
+                           'iperf3',
                            "{}".format(pair[0]),
                            "{}".format(pair[1]),
                            "{}, {}".format(mtus[0], mtus[3]),
diff --git a/utils/os_client.py b/utils/os_client.py
index e22ce19..63f9151 100644
--- a/utils/os_client.py
+++ b/utils/os_client.py
@@ -310,6 +310,13 @@
                     'cidr': '0.0.0.0/0',
                 },
                 {
+                    # iperf
+                    'ip_protocol': 'tcp',
+                    'from_port': 5001,
+                    'to_port': 5001,
+                    'cidr': '0.0.0.0/0',
+                },
+                {
                     # ping
                     'ip_protocol': 'icmp',
                     'from_port': -1,
diff --git a/utils/ssh.py b/utils/ssh.py
index f6d61a2..fb684bb 100644
--- a/utils/ssh.py
+++ b/utils/ssh.py
@@ -126,14 +126,14 @@
 
     def put_iperf3_deb_packages_at_vms(self, source_directory,
                                        destination_directory):
-        required_packages = ['iperf3', 'libiperf0', 'libsctp1']
+        required_packages = ['iperf', 'iperf3', 'libiperf0', 'libsctp1']
         iperf_deb_files = [pack for pack in os.listdir(source_directory) if
                            any(req in pack for req in required_packages) if
                            pack.endswith('.deb')]
         if not iperf_deb_files:
             raise BaseException(
-                "iperf3 *.deb packages are not found locally at path {}. "
-                "Please recheck 'iperf_deb_package_dir_path' variable in "
+                "iperf3 or iperf *.deb packages are not found locally at path"
+                " {}. Please recheck 'iperf_deb_package_dir_path' variable in "
                 "global_config.yaml and check *.deb packages are manually "
                 "copied there.".format(source_directory))
         for f in iperf_deb_files:
@@ -186,6 +186,7 @@
         mtu = transport.exec_command('cat /sys/class/net/{}/mtu'.format(iface))
         return mtu.decode("utf-8")
 
+
 class prepare_iperf(object):
 
     def __init__(self, fip, user='ubuntu', password='password',
@@ -194,10 +195,10 @@
         transport = SSHTransport(fip, user, password, private_key)
         config = utils.get_configuration()
 
-        # Install iperf3 using apt or downloaded deb package
+        # Install iperf, iperf3 using apt or downloaded deb packages
         internet_at_vms = utils.get_configuration().get("internet_at_vms")
         if internet_at_vms.lower() == 'false':
-            logger.info("Copying offline iperf3 deb packages, installing...")
+            logger.info("Copying offline iperf* deb packages, installing...")
             path_to_iperf_deb = (config.get('iperf_deb_package_dir_path') or
                                  "/opt/packages/")
             home_ubuntu = "/home/ubuntu/"
@@ -205,15 +206,16 @@
                                                      home_ubuntu)
             transport.exec_command('sudo dpkg -i {}*.deb'.format(home_ubuntu))
         else:
-            logger.info("Installing iperf3 using apt")
+            logger.info("Installing iperf, iperf3 using apt")
             preparation_cmd = config.get('iperf_prep_string') or ['']
             transport.exec_command(preparation_cmd)
             transport.exec_command('sudo apt-get update;'
-                                   'sudo apt-get install -y iperf3')
+                                   'sudo apt-get install -y iperf3 iperf')
 
         # Log whether iperf is installed with version
-        check = transport.exec_command('dpkg -l | grep iperf3')
-        logger.debug(check.decode('utf-8'))
+        check = transport.exec_command('dpkg -l | grep iperf')
+        logger.info(check.decode('utf-8'))
 
         # Staring iperf server
         transport.exec_command('nohup iperf3 -s > file 2>&1 &')
+        transport.exec_command('nohup iperf -s > file 2>&1 &')