Create new project/user for rally test
[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             conf.write(yaml.dump(vmtp_conf))
118
119     def run_vmtp(self):
120         """Run Vmtp and generate charts
121
122         Raises: Exception on error
123         """
124         assert self.cloud
125         new_env = dict(
126             os.environ,
127             OS_USERNAME=self.project.user.name,
128             OS_PROJECT_NAME=self.project.project.name,
129             OS_PROJECT_ID=self.project.project.id,
130             OS_PASSWORD=self.project.password)
131         try:
132             del new_env['OS_TENANT_NAME']
133             del new_env['OS_TENANT_ID']
134         except Exception:  # pylint: disable=broad-except
135             pass
136         cmd = ['vmtp', '-d', '--json', '{}/vmtp.json'.format(self.res_dir),
137                '-c', self.config]
138         output = subprocess.check_output(
139             cmd, stderr=subprocess.STDOUT, env=new_env)
140         self.__logger.info("%s\n%s", " ".join(cmd), output)
141         cmd = ['vmtp_genchart', '-c', '{}/vmtp.html'.format(self.res_dir),
142                '{}/vmtp.json'.format(self.res_dir)]
143         output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
144         self.__logger.info("%s\n%s", " ".join(cmd), output)
145         with open('{}/vmtp.json'.format(self.res_dir), 'r') as res_file:
146             self.details = json.load(res_file)
147
148     def run(self, **kwargs):
149         self.start_time = time.time()
150         status = testcase.TestCase.EX_RUN_ERROR
151         try:
152             assert self.cloud
153             assert super(Vmtp, self).run(**kwargs) == self.EX_OK
154             status = testcase.TestCase.EX_RUN_ERROR
155             if self.orig_cloud.get_role("admin"):
156                 role_name = "admin"
157             elif self.orig_cloud.get_role("Admin"):
158                 role_name = "Admin"
159             else:
160                 raise Exception("Cannot detect neither admin nor Admin")
161             self.orig_cloud.grant_role(
162                 role_name, user=self.project.user.id,
163                 project=self.project.project.id,
164                 domain=self.project.domain.id)
165             self.generate_keys()
166             self.write_config()
167             self.run_vmtp()
168             self.result = 100
169             status = testcase.TestCase.EX_OK
170         except subprocess.CalledProcessError as cpe:
171             self.__logger.error(
172                 "Exception when calling %s\n%s", cpe.cmd, cpe.output)
173             self.result = 0
174         except Exception:  # pylint: disable=broad-except
175             self.__logger.exception("Cannot run vmtp")
176             self.result = 0
177         self.stop_time = time.time()
178         return status
179
180     def clean(self):
181         try:
182             assert self.cloud
183             super(Vmtp, self).clean()
184             os.remove(self.privkey_filename)
185             os.remove(self.pubkey_filename)
186             self.cloud.delete_network("pns-internal-net_{}".format(self.guid))
187             self.cloud.delete_network("pns-internal-net2_{}".format(self.guid))
188         except Exception:  # pylint: disable=broad-except
189             pass