d7f97c18d8457fd754985b8f6ee9919b5da70752
[functest.git] / functest / opnfv_tests / openstack / shaker / shaker.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 Shaker_ wraps around popular system network testing tools like iperf, iperf3
12 and netperf (with help of flent). Shaker is able to deploy OpenStack instances
13 and networks in different topologies. Shaker scenario specifies the deployment
14 and list of tests to execute.
15
16 .. _Shaker: http://pyshaker.readthedocs.io/en/latest/
17 """
18
19 import logging
20 import os
21
22 import scp
23
24 from functest.core import singlevm
25 from functest.utils import env
26
27
28 class Shaker(singlevm.SingleVm2):
29     """Run shaker full+perf l2 and l3"""
30     # pylint: disable=too-many-instance-attributes
31
32     __logger = logging.getLogger(__name__)
33
34     filename = '/home/opnfv/functest/images/shaker-image.qcow2'
35     flavor_ram = 512
36     flavor_vcpus = 1
37     flavor_disk = 3
38     username = 'ubuntu'
39     port = 9000
40     ssh_connect_loops = 12
41     create_server_timeout = 300
42     shaker_timeout = '3600'
43     quota_instances = -1
44     quota_cores = -1
45
46     def __init__(self, **kwargs):
47         super(Shaker, self).__init__(**kwargs)
48         self.role = None
49
50     def check_requirements(self):
51         if self.count_active_hypervisors() < 2:
52             self.__logger.warning("Shaker requires at least 2 hypervisors")
53             self.is_skipped = True
54             self.project.clean()
55
56     def prepare(self):
57         super(Shaker, self).prepare()
58         self.cloud.create_security_group_rule(
59             self.sec.id, port_range_min=self.port, port_range_max=self.port,
60             protocol='tcp', direction='ingress')
61
62     def execute(self):
63         """
64         Returns:
65             - 0 if success
66             - 1 on operation error
67         """
68         assert self.ssh
69         endpoint = self.get_public_auth_url(self.orig_cloud)
70         self.__logger.debug("keystone endpoint: %s", endpoint)
71         if self.orig_cloud.get_role("admin"):
72             role_name = "admin"
73         elif self.orig_cloud.get_role("Admin"):
74             role_name = "Admin"
75         else:
76             raise Exception("Cannot detect neither admin nor Admin")
77         self.orig_cloud.grant_role(
78             role_name, user=self.project.user.id,
79             project=self.project.project.id,
80             domain=self.project.domain.id)
81         if not self.orig_cloud.get_role("heat_stack_owner"):
82             self.role = self.orig_cloud.create_role("heat_stack_owner")
83         self.orig_cloud.grant_role(
84             "heat_stack_owner", user=self.project.user.id,
85             project=self.project.project.id,
86             domain=self.project.domain.id)
87         self.orig_cloud.set_compute_quotas(
88             self.project.project.name,
89             instances=self.quota_instances,
90             cores=self.quota_cores)
91         scpc = scp.SCPClient(self.ssh.get_transport())
92         scpc.put('/home/opnfv/functest/conf/env_file', remote_path='~/')
93         if os.environ.get('OS_CACERT'):
94             scpc.put(os.environ.get('OS_CACERT'), remote_path='~/os_cacert')
95         (_, stdout, stderr) = self.ssh.exec_command(
96             'source ~/env_file && '
97             'export OS_INTERFACE=public && '
98             'export OS_AUTH_URL={} && '
99             'export OS_USERNAME={} && '
100             'export OS_PROJECT_NAME={} && '
101             'export OS_PROJECT_ID={} && '
102             'unset OS_TENANT_NAME && '
103             'unset OS_TENANT_ID && '
104             'unset OS_ENDPOINT_TYPE && '
105             'export OS_PASSWORD="{}" && '
106             '{}'
107             'env && '
108             'timeout {} shaker --debug --image-name {} --flavor-name {} '
109             '--server-endpoint {}:9000 --external-net {} --dns-nameservers {} '
110             '--scenario openstack/full_l2,'
111             'openstack/full_l3_east_west,'
112             'openstack/full_l3_north_south,'
113             'openstack/perf_l3_north_south '
114             '--report report.html --output report.json'.format(
115                 endpoint, self.project.user.name, self.project.project.name,
116                 self.project.project.id, self.project.password,
117                 'export OS_CACERT=~/os_cacert && ' if os.environ.get(
118                     'OS_CACERT') else '',
119                 self.shaker_timeout, self.image.name, self.flavor.name,
120                 self.fip.floating_ip_address, self.ext_net.id,
121                 env.get('NAMESERVER')))
122         self.__logger.info("output:\n%s", stdout.read().decode("utf-8"))
123         self.__logger.info("error:\n%s", stderr.read().decode("utf-8"))
124         if not os.path.exists(self.res_dir):
125             os.makedirs(self.res_dir)
126         try:
127             scpc.get('report.json', self.res_dir)
128             scpc.get('report.html', self.res_dir)
129         except scp.SCPException:
130             self.__logger.exception("cannot get report files")
131             return 1
132         return stdout.channel.recv_exit_status()
133
134     def clean(self):
135         super(Shaker, self).clean()
136         if self.role:
137             self.orig_cloud.delete_role(self.role.id)