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