Add Rally scenarios for testing floating IP
[functest.git] / functest / opnfv_tests / openstack / vmtp / vmtp.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2018 Orange and others.
4 #
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9
10 """
11 VMTP_ is a small python application that will automatically perform ping
12 connectivity, round trip time measurement (latency) and TCP/UDP throughput
13 measurement for the following East/West flows on any OpenStack deployment:
14
15 - VM to VM same network (private fixed IP, flow #1)
16 - VM to VM different network using fixed IP (same as intra-tenant L3 fixed IP,
17   flow #2)
18 - VM to VM different network using floating IP and NAT (same as floating IP
19   inter-tenant L3, flow #3)
20
21 .. _VMTP: http://vmtp.readthedocs.io/en/latest/
22 """
23
24 import json
25 import logging
26 import os
27 import subprocess
28 import tempfile
29 import time
30 import yaml
31
32 from xtesting.core import testcase
33
34 from functest.core import singlevm
35 from functest.utils import env
36
37
38 class Vmtp(singlevm.VmReady2):
39     """Class to run Vmtp_ as an OPNFV Functest testcase
40
41     .. _Vmtp: http://vmtp.readthedocs.io/en/latest/
42     """
43     # pylint: disable=too-many-instance-attributes
44
45     __logger = logging.getLogger(__name__)
46
47     filename = ('/home/opnfv/functest/images/'
48                 'ubuntu-14.04-server-cloudimg-amd64-disk1.img')
49     flavor_ram = 2048
50     flavor_vcpus = 1
51     flavor_disk = 0
52
53     def __init__(self, **kwargs):
54         if "case_name" not in kwargs:
55             kwargs["case_name"] = 'vmtp'
56         super(Vmtp, self).__init__(**kwargs)
57         self.config = "{}/vmtp.conf".format(self.res_dir)
58         (_, self.privkey_filename) = tempfile.mkstemp()
59         (_, self.pubkey_filename) = tempfile.mkstemp()
60
61     def create_network_resources(self):
62         """Create router
63
64         It creates a router which gateway is the external network detected.
65
66         Raises: expection on error
67         """
68         assert self.cloud
69         assert self.ext_net
70         self.router = self.cloud.create_router(
71             name='{}-router_{}'.format(self.case_name, self.guid),
72             ext_gateway_net_id=self.ext_net.id)
73         self.__logger.debug("router: %s", self.router)
74
75     def generate_keys(self):
76         """Generate Keys
77
78         Raises: Exception on error
79         """
80         assert self.cloud
81         name = "vmtp_{}".format(self.guid)
82         self.__logger.info("Creating keypair with name: '%s'", name)
83         keypair = self.cloud.create_keypair(name)
84         self.__logger.debug("keypair: %s", keypair)
85         with open(self.privkey_filename, 'w') as key_file:
86             key_file.write(keypair.private_key)
87         with open(self.pubkey_filename, 'w') as key_file:
88             key_file.write(keypair.public_key)
89         self.cloud.delete_keypair(keypair.id)
90
91     def write_config(self):
92         """Write vmtp.conf
93
94         Raises: Exception on error
95         """
96         assert self.cloud
97         if not os.path.exists(self.res_dir):
98             os.makedirs(self.res_dir)
99         cmd = ['vmtp', '-sc']
100         output = subprocess.check_output(cmd)
101         self.__logger.info("%s\n%s", " ".join(cmd), output)
102         with open(self.config, "w+") as conf:
103             vmtp_conf = yaml.load(output)
104             vmtp_conf["private_key_file"] = self.privkey_filename
105             vmtp_conf["public_key_file"] = self.pubkey_filename
106             vmtp_conf["image_name"] = str(self.image.name)
107             vmtp_conf["router_name"] = str(self.router.name)
108             vmtp_conf["flavor_type"] = str(self.flavor.name)
109             vmtp_conf["internal_network_name"] = [
110                 "pns-internal-net_{}".format(self.guid),
111                 "pns-internal-net2_{}".format(self.guid)]
112             vmtp_conf["vm_name_client"] = "TestClient_{}".format(self.guid)
113             vmtp_conf["vm_name_server"] = "TestServer_{}".format(self.guid)
114             vmtp_conf["security_group_name"] = "pns-security{}".format(
115                 self.guid)
116             vmtp_conf["dns_nameservers"] = [env.get('NAMESERVER')]
117             vmtp_conf["generic_retry_count"] = self.create_server_timeout // 2
118             conf.write(yaml.dump(vmtp_conf))
119
120     def run_vmtp(self):
121         """Run Vmtp and generate charts
122
123         Raises: Exception on error
124         """
125         assert self.cloud
126         new_env = dict(
127             os.environ,
128             OS_USERNAME=self.project.user.name,
129             OS_PROJECT_NAME=self.project.project.name,
130             OS_PROJECT_ID=self.project.project.id,
131             OS_PASSWORD=self.project.password)
132         try:
133             del new_env['OS_TENANT_NAME']
134             del new_env['OS_TENANT_ID']
135         except Exception:  # pylint: disable=broad-except
136             pass
137         cmd = ['vmtp', '-d', '--json', '{}/vmtp.json'.format(self.res_dir),
138                '-c', self.config]
139         output = subprocess.check_output(
140             cmd, stderr=subprocess.STDOUT, env=new_env)
141         self.__logger.info("%s\n%s", " ".join(cmd), output)
142         cmd = ['vmtp_genchart', '-c', '{}/vmtp.html'.format(self.res_dir),
143                '{}/vmtp.json'.format(self.res_dir)]
144         output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
145         self.__logger.info("%s\n%s", " ".join(cmd), output)
146         with open('{}/vmtp.json'.format(self.res_dir), 'r') as res_file:
147             self.details = json.load(res_file)
148
149     def run(self, **kwargs):
150         self.start_time = time.time()
151         status = testcase.TestCase.EX_RUN_ERROR
152         try:
153             assert self.cloud
154             assert super(Vmtp, self).run(**kwargs) == self.EX_OK
155             status = testcase.TestCase.EX_RUN_ERROR
156             if self.orig_cloud.get_role("admin"):
157                 role_name = "admin"
158             elif self.orig_cloud.get_role("Admin"):
159                 role_name = "Admin"
160             else:
161                 raise Exception("Cannot detect neither admin nor Admin")
162             self.orig_cloud.grant_role(
163                 role_name, user=self.project.user.id,
164                 project=self.project.project.id,
165                 domain=self.project.domain.id)
166             self.generate_keys()
167             self.write_config()
168             self.run_vmtp()
169             self.result = 100
170             status = testcase.TestCase.EX_OK
171         except subprocess.CalledProcessError as cpe:
172             self.__logger.error(
173                 "Exception when calling %s\n%s", cpe.cmd, cpe.output)
174             self.result = 0
175         except Exception:  # pylint: disable=broad-except
176             self.__logger.exception("Cannot run vmtp")
177             self.result = 0
178         self.stop_time = time.time()
179         return status
180
181     def clean(self):
182         try:
183             assert self.cloud
184             super(Vmtp, self).clean()
185             os.remove(self.privkey_filename)
186             os.remove(self.pubkey_filename)
187             self.cloud.delete_network("pns-internal-net_{}".format(self.guid))
188             self.cloud.delete_network("pns-internal-net2_{}".format(self.guid))
189         except Exception:  # pylint: disable=broad-except
190             pass