blob: adb872dbf4404f2c124dd0da04ea8eb96d8baac2 [file] [log] [blame]
Jude Cross986e3f52017-07-24 14:57:20 -07001# Copyright 2018 Rackspace US Inc. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
15import ipaddress
16import pkg_resources
17import random
18import shlex
Jude Cross986e3f52017-07-24 14:57:20 -070019import string
20import subprocess
21import tempfile
22
23from oslo_log import log as logging
24from oslo_utils import uuidutils
25from tempest import config
26from tempest.lib.common.utils import data_utils
27from tempest.lib.common.utils.linux import remote_client
Jude Cross986e3f52017-07-24 14:57:20 -070028from tempest.lib import exceptions
29from tempest import test
Michael Johnson04dc5cb2019-01-20 11:03:50 -080030import tenacity
Jude Cross986e3f52017-07-24 14:57:20 -070031
32from octavia_tempest_plugin import clients
33from octavia_tempest_plugin.common import constants as const
34from octavia_tempest_plugin.tests import validators
35from octavia_tempest_plugin.tests import waiters
36
37CONF = config.CONF
38LOG = logging.getLogger(__name__)
39
Michael Johnson04dc5cb2019-01-20 11:03:50 -080040RETRY_ATTEMPTS = 15
41RETRY_INITIAL_DELAY = 1
42RETRY_BACKOFF = 1
43RETRY_MAX = 5
44
Gregory Thiemonge29d17902019-04-30 15:06:17 +020045
Michael Johnson89bdbcd2020-03-19 15:59:19 -070046class LoadBalancerBaseTest(validators.ValidatorsMixin, test.BaseTestCase):
Jude Cross986e3f52017-07-24 14:57:20 -070047 """Base class for load balancer tests."""
48
49 # Setup cls.os_roles_lb_member. cls.os_primary, cls.os_roles_lb_member,
50 # and cls.os_roles_lb_admin credentials.
51 credentials = ['admin', 'primary',
52 ['lb_member', CONF.load_balancer.member_role],
53 ['lb_member2', CONF.load_balancer.member_role],
54 ['lb_admin', CONF.load_balancer.admin_role]]
55
56 client_manager = clients.ManagerV2
Adam Harwelle029af22018-05-24 17:13:28 -070057 webserver1_response = 1
58 webserver2_response = 5
Michael Johnsondfd818a2018-08-21 20:54:54 -070059 used_ips = []
Jude Cross986e3f52017-07-24 14:57:20 -070060
Michael Johnson89bdbcd2020-03-19 15:59:19 -070061 SRC_PORT_NUMBER_MIN = 32768
62 SRC_PORT_NUMBER_MAX = 61000
Gregory Thiemonge29d17902019-04-30 15:06:17 +020063 src_port_number = SRC_PORT_NUMBER_MIN
64
Jude Cross986e3f52017-07-24 14:57:20 -070065 @classmethod
66 def skip_checks(cls):
67 """Check if we should skip all of the children tests."""
68 super(LoadBalancerBaseTest, cls).skip_checks()
69
70 service_list = {
71 'load_balancer': CONF.service_available.load_balancer,
72 }
73
74 live_service_list = {
75 'compute': CONF.service_available.nova,
76 'image': CONF.service_available.glance,
77 'neutron': CONF.service_available.neutron
78 }
79
80 if not CONF.load_balancer.test_with_noop:
81 service_list.update(live_service_list)
82
83 for service, available in service_list.items():
84 if not available:
zhangzs2a6cf672018-11-10 16:13:11 +080085 skip_msg = ("{0} skipped as {1} service is not "
Jude Cross986e3f52017-07-24 14:57:20 -070086 "available.".format(cls.__name__, service))
87 raise cls.skipException(skip_msg)
88
89 # We must be able to reach our VIP and instances
90 if not (CONF.network.project_networks_reachable
91 or CONF.network.public_network_id):
92 msg = ('Either project_networks_reachable must be "true", or '
93 'public_network_id must be defined.')
94 raise cls.skipException(msg)
95
96 @classmethod
97 def setup_credentials(cls):
98 """Setup test credentials and network resources."""
99 # Do not auto create network resources
100 cls.set_network_resources()
101 super(LoadBalancerBaseTest, cls).setup_credentials()
102
103 @classmethod
104 def setup_clients(cls):
105 """Setup client aliases."""
106 super(LoadBalancerBaseTest, cls).setup_clients()
107 cls.lb_mem_float_ip_client = cls.os_roles_lb_member.floating_ips_client
108 cls.lb_mem_keypairs_client = cls.os_roles_lb_member.keypairs_client
109 cls.lb_mem_net_client = cls.os_roles_lb_member.networks_client
110 cls.lb_mem_ports_client = cls.os_roles_lb_member.ports_client
111 cls.lb_mem_routers_client = cls.os_roles_lb_member.routers_client
112 cls.lb_mem_SG_client = cls.os_roles_lb_member.security_groups_client
113 cls.lb_mem_SGr_client = (
114 cls.os_roles_lb_member.security_group_rules_client)
115 cls.lb_mem_servers_client = cls.os_roles_lb_member.servers_client
116 cls.lb_mem_subnet_client = cls.os_roles_lb_member.subnets_client
117 cls.mem_lb_client = cls.os_roles_lb_member.loadbalancer_client
Jude Crossfbbd2b42017-08-09 15:21:04 -0700118 cls.mem_listener_client = cls.os_roles_lb_member.listener_client
Adam Harwell8ffce3e2018-05-01 21:18:44 -0700119 cls.mem_pool_client = cls.os_roles_lb_member.pool_client
Adam Harwellde3e0542018-05-03 18:21:06 -0700120 cls.mem_member_client = cls.os_roles_lb_member.member_client
Adam Harwell60ed9d92018-05-10 13:23:13 -0700121 cls.mem_healthmonitor_client = (
122 cls.os_roles_lb_member.healthmonitor_client)
Adam Harwell446f8be2018-05-24 16:51:03 -0700123 cls.mem_l7policy_client = cls.os_roles_lb_member.l7policy_client
Adam Harwelle029af22018-05-24 17:13:28 -0700124 cls.mem_l7rule_client = cls.os_roles_lb_member.l7rule_client
Michael Johnson2b10e0a2019-01-25 15:42:13 -0800125 cls.lb_admin_amphora_client = cls.os_roles_lb_admin.amphora_client
Michael Johnsonaff2e862019-01-11 16:38:00 -0800126 cls.lb_admin_flavor_profile_client = (
127 cls.os_roles_lb_admin.flavor_profile_client)
Michael Johnsona2d03072019-01-14 17:18:21 -0800128 cls.lb_admin_flavor_client = cls.os_roles_lb_admin.flavor_client
129 cls.mem_flavor_client = cls.os_roles_lb_member.flavor_client
Michael Johnsonfc223fe2019-01-15 16:40:05 -0800130 cls.mem_provider_client = cls.os_roles_lb_member.provider_client
Carlos Goncalvesc2e12162019-02-14 23:57:44 +0100131 cls.os_admin_servers_client = cls.os_admin.servers_client
Adam Harwellc2aa20c2019-11-20 11:15:07 -0800132 cls.lb_admin_flavor_capabilities_client = (
Michael Johnson77df0322019-01-15 18:27:58 -0800133 cls.os_roles_lb_admin.flavor_capabilities_client)
Adam Harwellc2aa20c2019-11-20 11:15:07 -0800134 cls.lb_admin_availability_zone_capabilities_client = (
135 cls.os_roles_lb_admin.availability_zone_capabilities_client)
136 cls.lb_admin_availability_zone_profile_client = (
137 cls.os_roles_lb_admin.availability_zone_profile_client)
138 cls.lb_admin_availability_zone_client = (
139 cls.os_roles_lb_admin.availability_zone_client)
140 cls.mem_availability_zone_client = (
141 cls.os_roles_lb_member.availability_zone_client)
Jude Cross986e3f52017-07-24 14:57:20 -0700142
143 @classmethod
144 def resource_setup(cls):
145 """Setup resources needed by the tests."""
146 super(LoadBalancerBaseTest, cls).resource_setup()
147
148 conf_lb = CONF.load_balancer
149
Michael Johnsondfd818a2018-08-21 20:54:54 -0700150 cls.api_version = cls.mem_lb_client.get_max_api_version()
151
Jude Cross986e3f52017-07-24 14:57:20 -0700152 if conf_lb.test_subnet_override and not conf_lb.test_network_override:
153 raise exceptions.InvalidConfiguration(
154 "Configuration value test_network_override must be "
155 "specified if test_subnet_override is used.")
156
Maciej Józefczykb6df5f82019-12-10 10:12:30 +0000157 # Get loadbalancing algorithms supported by provider driver.
158 try:
159 algorithms = const.SUPPORTED_LB_ALGORITHMS[
160 CONF.load_balancer.provider]
161 except KeyError:
162 algorithms = const.SUPPORTED_LB_ALGORITHMS['default']
163 # Set default algorithm as first from the list.
164 cls.lb_algorithm = algorithms[0]
165
Jude Cross986e3f52017-07-24 14:57:20 -0700166 show_subnet = cls.lb_mem_subnet_client.show_subnet
167 if CONF.load_balancer.test_with_noop:
168 cls.lb_member_vip_net = {'id': uuidutils.generate_uuid()}
169 cls.lb_member_vip_subnet = {'id': uuidutils.generate_uuid()}
170 cls.lb_member_1_net = {'id': uuidutils.generate_uuid()}
171 cls.lb_member_1_subnet = {'id': uuidutils.generate_uuid()}
172 cls.lb_member_2_net = {'id': uuidutils.generate_uuid()}
173 cls.lb_member_2_subnet = {'id': uuidutils.generate_uuid()}
174 if CONF.load_balancer.test_with_ipv6:
Michael Johnson5a16ad32018-10-18 14:49:11 -0700175 cls.lb_member_vip_ipv6_net = {'id': uuidutils.generate_uuid()}
Jude Cross986e3f52017-07-24 14:57:20 -0700176 cls.lb_member_vip_ipv6_subnet = {'id':
177 uuidutils.generate_uuid()}
178 cls.lb_member_1_ipv6_subnet = {'id': uuidutils.generate_uuid()}
179 cls.lb_member_2_ipv6_subnet = {'id': uuidutils.generate_uuid()}
Michael Johnson590fbe12019-07-03 14:30:01 -0700180 cls.lb_member_vip_ipv6_subnet_stateful = True
Jude Cross986e3f52017-07-24 14:57:20 -0700181 return
182 elif CONF.load_balancer.test_network_override:
183 if conf_lb.test_subnet_override:
184 override_subnet = show_subnet(conf_lb.test_subnet_override)
185 else:
186 override_subnet = None
187
188 show_net = cls.lb_mem_net_client.show_network
189 override_network = show_net(conf_lb.test_network_override)
190 override_network = override_network.get('network')
191
192 cls.lb_member_vip_net = override_network
193 cls.lb_member_vip_subnet = override_subnet
194 cls.lb_member_1_net = override_network
195 cls.lb_member_1_subnet = override_subnet
196 cls.lb_member_2_net = override_network
197 cls.lb_member_2_subnet = override_subnet
198
199 if (CONF.load_balancer.test_with_ipv6 and
200 conf_lb.test_IPv6_subnet_override):
201 override_ipv6_subnet = show_subnet(
202 conf_lb.test_IPv6_subnet_override)
203 cls.lb_member_vip_ipv6_subnet = override_ipv6_subnet
204 cls.lb_member_1_ipv6_subnet = override_ipv6_subnet
205 cls.lb_member_2_ipv6_subnet = override_ipv6_subnet
Michael Johnson590fbe12019-07-03 14:30:01 -0700206 cls.lb_member_vip_ipv6_subnet_stateful = False
207 if (override_ipv6_subnet[0]['ipv6_address_mode'] ==
208 'dhcpv6-stateful'):
209 cls.lb_member_vip_ipv6_subnet_stateful = True
Jude Cross986e3f52017-07-24 14:57:20 -0700210 else:
211 cls.lb_member_vip_ipv6_subnet = None
212 cls.lb_member_1_ipv6_subnet = None
213 cls.lb_member_2_ipv6_subnet = None
214 else:
215 cls._create_networks()
216
217 LOG.debug('Octavia Setup: lb_member_vip_net = {}'.format(
218 cls.lb_member_vip_net[const.ID]))
219 if cls.lb_member_vip_subnet:
220 LOG.debug('Octavia Setup: lb_member_vip_subnet = {}'.format(
221 cls.lb_member_vip_subnet[const.ID]))
222 LOG.debug('Octavia Setup: lb_member_1_net = {}'.format(
223 cls.lb_member_1_net[const.ID]))
224 if cls.lb_member_1_subnet:
225 LOG.debug('Octavia Setup: lb_member_1_subnet = {}'.format(
226 cls.lb_member_1_subnet[const.ID]))
227 LOG.debug('Octavia Setup: lb_member_2_net = {}'.format(
228 cls.lb_member_2_net[const.ID]))
229 if cls.lb_member_2_subnet:
230 LOG.debug('Octavia Setup: lb_member_2_subnet = {}'.format(
231 cls.lb_member_2_subnet[const.ID]))
Michael Johnson124ba8b2018-08-30 16:06:05 -0700232 if CONF.load_balancer.test_with_ipv6:
233 if cls.lb_member_vip_ipv6_subnet:
234 LOG.debug('Octavia Setup: lb_member_vip_ipv6_subnet = '
235 '{}'.format(cls.lb_member_vip_ipv6_subnet[const.ID]))
236 if cls.lb_member_1_ipv6_subnet:
237 LOG.debug('Octavia Setup: lb_member_1_ipv6_subnet = {}'.format(
238 cls.lb_member_1_ipv6_subnet[const.ID]))
239 if cls.lb_member_2_ipv6_subnet:
240 LOG.debug('Octavia Setup: lb_member_2_ipv6_subnet = {}'.format(
241 cls.lb_member_2_ipv6_subnet[const.ID]))
Jude Cross986e3f52017-07-24 14:57:20 -0700242
Jude Cross986e3f52017-07-24 14:57:20 -0700243 @classmethod
Michael Johnson04dc5cb2019-01-20 11:03:50 -0800244 # Neutron can be slow to clean up ports from the subnets/networks.
245 # Retry this delete a few times if we get a "Conflict" error to give
246 # neutron time to fully cleanup the ports.
247 @tenacity.retry(
248 retry=tenacity.retry_if_exception_type(exceptions.Conflict),
249 wait=tenacity.wait_incrementing(
250 RETRY_INITIAL_DELAY, RETRY_BACKOFF, RETRY_MAX),
251 stop=tenacity.stop_after_attempt(RETRY_ATTEMPTS))
252 def _logging_delete_network(cls, net_id):
253 try:
254 cls.lb_mem_net_client.delete_network(net_id)
255 except Exception:
256 LOG.error('Unable to delete network {}. Active ports:'.format(
257 net_id))
258 LOG.error(cls.lb_mem_ports_client.list_ports())
259 raise
260
261 @classmethod
262 # Neutron can be slow to clean up ports from the subnets/networks.
263 # Retry this delete a few times if we get a "Conflict" error to give
264 # neutron time to fully cleanup the ports.
265 @tenacity.retry(
266 retry=tenacity.retry_if_exception_type(exceptions.Conflict),
267 wait=tenacity.wait_incrementing(
268 RETRY_INITIAL_DELAY, RETRY_BACKOFF, RETRY_MAX),
269 stop=tenacity.stop_after_attempt(RETRY_ATTEMPTS))
270 def _logging_delete_subnet(cls, subnet_id):
271 try:
272 cls.lb_mem_subnet_client.delete_subnet(subnet_id)
273 except Exception:
274 LOG.error('Unable to delete subnet {}. Active ports:'.format(
275 subnet_id))
276 LOG.error(cls.lb_mem_ports_client.list_ports())
277 raise
278
279 @classmethod
Jude Cross986e3f52017-07-24 14:57:20 -0700280 def _create_networks(cls):
281 """Creates networks, subnets, and routers used in tests.
282
283 The following are expected to be defined and available to the tests:
284 cls.lb_member_vip_net
285 cls.lb_member_vip_subnet
286 cls.lb_member_vip_ipv6_subnet (optional)
287 cls.lb_member_1_net
288 cls.lb_member_1_subnet
289 cls.lb_member_1_ipv6_subnet (optional)
290 cls.lb_member_2_net
291 cls.lb_member_2_subnet
292 cls.lb_member_2_ipv6_subnet (optional)
293 """
294
295 # Create tenant VIP network
296 network_kwargs = {
297 'name': data_utils.rand_name("lb_member_vip_network")}
298 if CONF.network_feature_enabled.port_security:
Andreas Jaeger4215b702020-03-28 20:13:46 +0100299 # Note: Allowed Address Pairs requires port security
300 network_kwargs['port_security_enabled'] = True
Jude Cross986e3f52017-07-24 14:57:20 -0700301 result = cls.lb_mem_net_client.create_network(**network_kwargs)
302 cls.lb_member_vip_net = result['network']
303 LOG.info('lb_member_vip_net: {}'.format(cls.lb_member_vip_net))
304 cls.addClassResourceCleanup(
305 waiters.wait_for_not_found,
Michael Johnson04dc5cb2019-01-20 11:03:50 -0800306 cls._logging_delete_network,
Jude Cross986e3f52017-07-24 14:57:20 -0700307 cls.lb_mem_net_client.show_network,
308 cls.lb_member_vip_net['id'])
309
310 # Create tenant VIP subnet
311 subnet_kwargs = {
312 'name': data_utils.rand_name("lb_member_vip_subnet"),
313 'network_id': cls.lb_member_vip_net['id'],
314 'cidr': CONF.load_balancer.vip_subnet_cidr,
315 'ip_version': 4}
316 result = cls.lb_mem_subnet_client.create_subnet(**subnet_kwargs)
317 cls.lb_member_vip_subnet = result['subnet']
318 LOG.info('lb_member_vip_subnet: {}'.format(cls.lb_member_vip_subnet))
319 cls.addClassResourceCleanup(
320 waiters.wait_for_not_found,
Michael Johnson04dc5cb2019-01-20 11:03:50 -0800321 cls._logging_delete_subnet,
Jude Cross986e3f52017-07-24 14:57:20 -0700322 cls.lb_mem_subnet_client.show_subnet,
323 cls.lb_member_vip_subnet['id'])
324
325 # Create tenant VIP IPv6 subnet
326 if CONF.load_balancer.test_with_ipv6:
Adam Harwell2b9432f2019-05-02 13:56:09 -0600327 # See if ipv6-private-subnet exists and use it if so.
328 priv_ipv6_subnet = cls.os_admin.subnets_client.list_subnets(
329 name='ipv6-private-subnet')['subnets']
Michael Johnson5a16ad32018-10-18 14:49:11 -0700330
Michael Johnson590fbe12019-07-03 14:30:01 -0700331 cls.lb_member_vip_ipv6_subnet_stateful = False
Adam Harwell2b9432f2019-05-02 13:56:09 -0600332 if len(priv_ipv6_subnet) == 1:
Carlos Goncalves84af48c2019-07-25 15:51:30 +0200333 if (priv_ipv6_subnet[0]['ipv6_address_mode'] ==
334 'dhcpv6-stateful'):
335 cls.lb_member_vip_ipv6_subnet_stateful = True
Adam Harwell2b9432f2019-05-02 13:56:09 -0600336 cls.lb_member_vip_ipv6_subnet = priv_ipv6_subnet[0]
Michael Johnson5a16ad32018-10-18 14:49:11 -0700337 cls.lb_member_vip_ipv6_net = {
Adam Harwell2b9432f2019-05-02 13:56:09 -0600338 'id': priv_ipv6_subnet[0]['network_id']}
Michael Johnson5a16ad32018-10-18 14:49:11 -0700339 else:
340 subnet_kwargs = {
341 'name': data_utils.rand_name("lb_member_vip_ipv6_subnet"),
342 'network_id': cls.lb_member_vip_net['id'],
343 'cidr': CONF.load_balancer.vip_ipv6_subnet_cidr,
344 'ip_version': 6}
345 result = cls.lb_mem_subnet_client.create_subnet(
346 **subnet_kwargs)
Michael Johnson7c5b9012019-05-28 11:02:29 -0700347 cls.lb_member_vip_ipv6_net = cls.lb_member_vip_net
Michael Johnson5a16ad32018-10-18 14:49:11 -0700348 cls.lb_member_vip_ipv6_subnet = result['subnet']
349 cls.addClassResourceCleanup(
350 waiters.wait_for_not_found,
Michael Johnson04dc5cb2019-01-20 11:03:50 -0800351 cls._logging_delete_subnet,
Michael Johnson5a16ad32018-10-18 14:49:11 -0700352 cls.lb_mem_subnet_client.show_subnet,
353 cls.lb_member_vip_ipv6_subnet['id'])
Carlos Goncalves84af48c2019-07-25 15:51:30 +0200354
Jude Cross986e3f52017-07-24 14:57:20 -0700355 LOG.info('lb_member_vip_ipv6_subnet: {}'.format(
356 cls.lb_member_vip_ipv6_subnet))
Jude Cross986e3f52017-07-24 14:57:20 -0700357
358 # Create tenant member 1 network
359 network_kwargs = {
360 'name': data_utils.rand_name("lb_member_1_network")}
361 if CONF.network_feature_enabled.port_security:
362 if CONF.load_balancer.enable_security_groups:
363 network_kwargs['port_security_enabled'] = True
364 else:
365 network_kwargs['port_security_enabled'] = False
366 result = cls.lb_mem_net_client.create_network(**network_kwargs)
367 cls.lb_member_1_net = result['network']
368 LOG.info('lb_member_1_net: {}'.format(cls.lb_member_1_net))
369 cls.addClassResourceCleanup(
370 waiters.wait_for_not_found,
Michael Johnson04dc5cb2019-01-20 11:03:50 -0800371 cls._logging_delete_network,
Jude Cross986e3f52017-07-24 14:57:20 -0700372 cls.lb_mem_net_client.show_network,
373 cls.lb_member_1_net['id'])
374
375 # Create tenant member 1 subnet
376 subnet_kwargs = {
377 'name': data_utils.rand_name("lb_member_1_subnet"),
378 'network_id': cls.lb_member_1_net['id'],
379 'cidr': CONF.load_balancer.member_1_ipv4_subnet_cidr,
380 'ip_version': 4}
381 result = cls.lb_mem_subnet_client.create_subnet(**subnet_kwargs)
382 cls.lb_member_1_subnet = result['subnet']
383 LOG.info('lb_member_1_subnet: {}'.format(cls.lb_member_1_subnet))
384 cls.addClassResourceCleanup(
385 waiters.wait_for_not_found,
Michael Johnson04dc5cb2019-01-20 11:03:50 -0800386 cls._logging_delete_subnet,
Jude Cross986e3f52017-07-24 14:57:20 -0700387 cls.lb_mem_subnet_client.show_subnet,
388 cls.lb_member_1_subnet['id'])
389
390 # Create tenant member 1 ipv6 subnet
391 if CONF.load_balancer.test_with_ipv6:
392 subnet_kwargs = {
393 'name': data_utils.rand_name("lb_member_1_ipv6_subnet"),
394 'network_id': cls.lb_member_1_net['id'],
395 'cidr': CONF.load_balancer.member_1_ipv6_subnet_cidr,
396 'ip_version': 6}
397 result = cls.lb_mem_subnet_client.create_subnet(**subnet_kwargs)
Michael Johnsonbf916df2018-10-17 10:59:28 -0700398 cls.lb_member_1_subnet_prefix = (
399 CONF.load_balancer.member_1_ipv6_subnet_cidr.rpartition('/')[2]
400 )
401 assert(cls.lb_member_1_subnet_prefix.isdigit())
Jude Cross986e3f52017-07-24 14:57:20 -0700402 cls.lb_member_1_ipv6_subnet = result['subnet']
403 LOG.info('lb_member_1_ipv6_subnet: {}'.format(
404 cls.lb_member_1_ipv6_subnet))
405 cls.addClassResourceCleanup(
406 waiters.wait_for_not_found,
Michael Johnson04dc5cb2019-01-20 11:03:50 -0800407 cls._logging_delete_subnet,
Jude Cross986e3f52017-07-24 14:57:20 -0700408 cls.lb_mem_subnet_client.show_subnet,
409 cls.lb_member_1_ipv6_subnet['id'])
410
411 # Create tenant member 2 network
412 network_kwargs = {
413 'name': data_utils.rand_name("lb_member_2_network")}
414 if CONF.network_feature_enabled.port_security:
415 if CONF.load_balancer.enable_security_groups:
416 network_kwargs['port_security_enabled'] = True
417 else:
418 network_kwargs['port_security_enabled'] = False
419 result = cls.lb_mem_net_client.create_network(**network_kwargs)
420 cls.lb_member_2_net = result['network']
421 LOG.info('lb_member_2_net: {}'.format(cls.lb_member_2_net))
422 cls.addClassResourceCleanup(
423 waiters.wait_for_not_found,
Michael Johnson04dc5cb2019-01-20 11:03:50 -0800424 cls._logging_delete_network,
Jude Cross986e3f52017-07-24 14:57:20 -0700425 cls.lb_mem_net_client.show_network,
426 cls.lb_member_2_net['id'])
427
428 # Create tenant member 2 subnet
429 subnet_kwargs = {
430 'name': data_utils.rand_name("lb_member_2_subnet"),
431 'network_id': cls.lb_member_2_net['id'],
432 'cidr': CONF.load_balancer.member_2_ipv4_subnet_cidr,
433 'ip_version': 4}
434 result = cls.lb_mem_subnet_client.create_subnet(**subnet_kwargs)
435 cls.lb_member_2_subnet = result['subnet']
436 LOG.info('lb_member_2_subnet: {}'.format(cls.lb_member_2_subnet))
437 cls.addClassResourceCleanup(
438 waiters.wait_for_not_found,
Michael Johnson04dc5cb2019-01-20 11:03:50 -0800439 cls._logging_delete_subnet,
Jude Cross986e3f52017-07-24 14:57:20 -0700440 cls.lb_mem_subnet_client.show_subnet,
441 cls.lb_member_2_subnet['id'])
442
443 # Create tenant member 2 ipv6 subnet
444 if CONF.load_balancer.test_with_ipv6:
445 subnet_kwargs = {
446 'name': data_utils.rand_name("lb_member_2_ipv6_subnet"),
447 'network_id': cls.lb_member_2_net['id'],
448 'cidr': CONF.load_balancer.member_2_ipv6_subnet_cidr,
449 'ip_version': 6}
450 result = cls.lb_mem_subnet_client.create_subnet(**subnet_kwargs)
Michael Johnsonbf916df2018-10-17 10:59:28 -0700451 cls.lb_member_2_subnet_prefix = (
452 CONF.load_balancer.member_2_ipv6_subnet_cidr.rpartition('/')[2]
453 )
454 assert(cls.lb_member_2_subnet_prefix.isdigit())
Jude Cross986e3f52017-07-24 14:57:20 -0700455 cls.lb_member_2_ipv6_subnet = result['subnet']
456 LOG.info('lb_member_2_ipv6_subnet: {}'.format(
457 cls.lb_member_2_ipv6_subnet))
458 cls.addClassResourceCleanup(
459 waiters.wait_for_not_found,
Michael Johnson04dc5cb2019-01-20 11:03:50 -0800460 cls._logging_delete_subnet,
Jude Cross986e3f52017-07-24 14:57:20 -0700461 cls.lb_mem_subnet_client.show_subnet,
462 cls.lb_member_2_ipv6_subnet['id'])
463
Adam Harwellcd72b562018-05-07 11:37:22 -0700464 @classmethod
Michael Johnson07c9a632018-06-07 13:27:42 -0700465 def _setup_lb_network_kwargs(cls, lb_kwargs, ip_version=None,
466 use_fixed_ip=False):
Adam Harwell60ed9d92018-05-10 13:23:13 -0700467 if not ip_version:
468 ip_version = 6 if CONF.load_balancer.test_with_ipv6 else 4
Michael Johnson5a16ad32018-10-18 14:49:11 -0700469 if cls.lb_member_vip_subnet or cls.lb_member_vip_ipv6_subnet:
Adam Harwellcd72b562018-05-07 11:37:22 -0700470 ip_index = data_utils.rand_int_id(start=10, end=100)
Michael Johnsondfd818a2018-08-21 20:54:54 -0700471 while ip_index in cls.used_ips:
472 ip_index = data_utils.rand_int_id(start=10, end=100)
473 cls.used_ips.append(ip_index)
Adam Harwellcd72b562018-05-07 11:37:22 -0700474 if ip_version == 4:
Adam Harwellcd72b562018-05-07 11:37:22 -0700475 subnet_id = cls.lb_member_vip_subnet[const.ID]
Michael Johnson5a16ad32018-10-18 14:49:11 -0700476 if CONF.load_balancer.test_with_noop:
477 lb_vip_address = '198.18.33.33'
478 else:
479 subnet = cls.os_admin.subnets_client.show_subnet(subnet_id)
480 network = ipaddress.IPv4Network(subnet['subnet']['cidr'])
481 lb_vip_address = str(network[ip_index])
Adam Harwellcd72b562018-05-07 11:37:22 -0700482 else:
Adam Harwellcd72b562018-05-07 11:37:22 -0700483 subnet_id = cls.lb_member_vip_ipv6_subnet[const.ID]
Michael Johnson5a16ad32018-10-18 14:49:11 -0700484 if CONF.load_balancer.test_with_noop:
485 lb_vip_address = '2001:db8:33:33:33:33:33:33'
486 else:
487 subnet = cls.os_admin.subnets_client.show_subnet(subnet_id)
488 network = ipaddress.IPv6Network(subnet['subnet']['cidr'])
489 lb_vip_address = str(network[ip_index])
Michael Johnson590fbe12019-07-03 14:30:01 -0700490 # If the subnet is IPv6 slaac or dhcpv6-stateless
491 # neutron does not allow a fixed IP
492 if not cls.lb_member_vip_ipv6_subnet_stateful:
493 use_fixed_ip = False
Adam Harwellcd72b562018-05-07 11:37:22 -0700494 lb_kwargs[const.VIP_SUBNET_ID] = subnet_id
Michael Johnson07c9a632018-06-07 13:27:42 -0700495 if use_fixed_ip:
496 lb_kwargs[const.VIP_ADDRESS] = lb_vip_address
Adam Harwellcd72b562018-05-07 11:37:22 -0700497 if CONF.load_balancer.test_with_noop:
498 lb_kwargs[const.VIP_NETWORK_ID] = (
499 cls.lb_member_vip_net[const.ID])
Carlos Goncalvesbb238552020-01-15 10:10:55 +0000500 if ip_version == 6:
501 lb_kwargs[const.VIP_ADDRESS] = lb_vip_address
Adam Harwellcd72b562018-05-07 11:37:22 -0700502 else:
503 lb_kwargs[const.VIP_NETWORK_ID] = cls.lb_member_vip_net[const.ID]
504 lb_kwargs[const.VIP_SUBNET_ID] = None
505
506
507class LoadBalancerBaseTestWithCompute(LoadBalancerBaseTest):
508 @classmethod
509 def resource_setup(cls):
510 super(LoadBalancerBaseTestWithCompute, cls).resource_setup()
511 # If validation is disabled in this cloud, we won't be able to
512 # start the webservers, so don't even boot them.
513 if not CONF.validation.run_validation:
514 return
515
516 # Create a keypair for the webservers
517 keypair_name = data_utils.rand_name('lb_member_keypair')
518 result = cls.lb_mem_keypairs_client.create_keypair(
519 name=keypair_name)
520 cls.lb_member_keypair = result['keypair']
521 LOG.info('lb_member_keypair: {}'.format(cls.lb_member_keypair))
522 cls.addClassResourceCleanup(
523 waiters.wait_for_not_found,
524 cls.lb_mem_keypairs_client.delete_keypair,
525 cls.lb_mem_keypairs_client.show_keypair,
526 keypair_name)
527
528 if (CONF.load_balancer.enable_security_groups and
529 CONF.network_feature_enabled.port_security):
530 # Set up the security group for the webservers
531 SG_name = data_utils.rand_name('lb_member_SG')
532 cls.lb_member_sec_group = (
533 cls.lb_mem_SG_client.create_security_group(
534 name=SG_name)['security_group'])
535 cls.addClassResourceCleanup(
536 waiters.wait_for_not_found,
537 cls.lb_mem_SG_client.delete_security_group,
538 cls.lb_mem_SG_client.show_security_group,
539 cls.lb_member_sec_group['id'])
540
541 # Create a security group rule to allow 80-81 (test webservers)
542 SGr = cls.lb_mem_SGr_client.create_security_group_rule(
543 direction='ingress',
544 security_group_id=cls.lb_member_sec_group['id'],
545 protocol='tcp',
546 ethertype='IPv4',
547 port_range_min=80,
548 port_range_max=81)['security_group_rule']
549 cls.addClassResourceCleanup(
550 waiters.wait_for_not_found,
551 cls.lb_mem_SGr_client.delete_security_group_rule,
552 cls.lb_mem_SGr_client.show_security_group_rule,
553 SGr['id'])
Gregory Thiemonge29d17902019-04-30 15:06:17 +0200554 # Create a security group rule to allow UDP 80-81 (test webservers)
555 SGr = cls.lb_mem_SGr_client.create_security_group_rule(
556 direction='ingress',
557 security_group_id=cls.lb_member_sec_group['id'],
558 protocol='udp',
559 ethertype='IPv4',
560 port_range_min=80,
561 port_range_max=81)['security_group_rule']
562 cls.addClassResourceCleanup(
563 waiters.wait_for_not_found,
564 cls.lb_mem_SGr_client.delete_security_group_rule,
565 cls.lb_mem_SGr_client.show_security_group_rule,
566 SGr['id'])
567 # Create a security group rule to allow UDP 9999 (test webservers)
568 # Port 9999 is used to illustrate health monitor ERRORs on closed
569 # ports.
570 SGr = cls.lb_mem_SGr_client.create_security_group_rule(
571 direction='ingress',
572 security_group_id=cls.lb_member_sec_group['id'],
573 protocol='udp',
574 ethertype='IPv4',
575 port_range_min=9999,
576 port_range_max=9999)['security_group_rule']
577 cls.addClassResourceCleanup(
578 waiters.wait_for_not_found,
579 cls.lb_mem_SGr_client.delete_security_group_rule,
580 cls.lb_mem_SGr_client.show_security_group_rule,
581 SGr['id'])
Adam Harwellcd72b562018-05-07 11:37:22 -0700582 # Create a security group rule to allow 22 (ssh)
583 SGr = cls.lb_mem_SGr_client.create_security_group_rule(
584 direction='ingress',
585 security_group_id=cls.lb_member_sec_group['id'],
586 protocol='tcp',
587 ethertype='IPv4',
588 port_range_min=22,
589 port_range_max=22)['security_group_rule']
590 cls.addClassResourceCleanup(
591 waiters.wait_for_not_found,
592 cls.lb_mem_SGr_client.delete_security_group_rule,
593 cls.lb_mem_SGr_client.show_security_group_rule,
594 SGr['id'])
595 if CONF.load_balancer.test_with_ipv6:
596 # Create a security group rule to allow 80-81 (test webservers)
597 SGr = cls.lb_mem_SGr_client.create_security_group_rule(
598 direction='ingress',
599 security_group_id=cls.lb_member_sec_group['id'],
600 protocol='tcp',
601 ethertype='IPv6',
602 port_range_min=80,
603 port_range_max=81)['security_group_rule']
604 cls.addClassResourceCleanup(
605 waiters.wait_for_not_found,
606 cls.lb_mem_SGr_client.delete_security_group_rule,
607 cls.lb_mem_SGr_client.show_security_group_rule,
608 SGr['id'])
Gregory Thiemonge29d17902019-04-30 15:06:17 +0200609 # Create a security group rule to allow UDP 80-81 (test
610 # webservers)
611 SGr = cls.lb_mem_SGr_client.create_security_group_rule(
612 direction='ingress',
613 security_group_id=cls.lb_member_sec_group['id'],
614 protocol='udp',
615 ethertype='IPv6',
616 port_range_min=80,
617 port_range_max=81)['security_group_rule']
618 cls.addClassResourceCleanup(
619 waiters.wait_for_not_found,
620 cls.lb_mem_SGr_client.delete_security_group_rule,
621 cls.lb_mem_SGr_client.show_security_group_rule,
622 SGr['id'])
Adam Harwellcd72b562018-05-07 11:37:22 -0700623 # Create a security group rule to allow 22 (ssh)
624 SGr = cls.lb_mem_SGr_client.create_security_group_rule(
625 direction='ingress',
626 security_group_id=cls.lb_member_sec_group['id'],
627 protocol='tcp',
628 ethertype='IPv6',
629 port_range_min=22,
630 port_range_max=22)['security_group_rule']
631 cls.addClassResourceCleanup(
632 waiters.wait_for_not_found,
633 cls.lb_mem_SGr_client.delete_security_group_rule,
634 cls.lb_mem_SGr_client.show_security_group_rule,
635 SGr['id'])
636
637 LOG.info('lb_member_sec_group: {}'.format(cls.lb_member_sec_group))
638
639 # Create webserver 1 instance
640 server_details = cls._create_webserver('lb_member_webserver1',
641 cls.lb_member_1_net)
642
643 cls.lb_member_webserver1 = server_details['server']
644 cls.webserver1_ip = server_details.get('ipv4_address')
645 cls.webserver1_ipv6 = server_details.get('ipv6_address')
646 cls.webserver1_public_ip = server_details['public_ipv4_address']
647
648 LOG.debug('Octavia Setup: lb_member_webserver1 = {}'.format(
649 cls.lb_member_webserver1[const.ID]))
650 LOG.debug('Octavia Setup: webserver1_ip = {}'.format(
651 cls.webserver1_ip))
652 LOG.debug('Octavia Setup: webserver1_ipv6 = {}'.format(
653 cls.webserver1_ipv6))
654 LOG.debug('Octavia Setup: webserver1_public_ip = {}'.format(
655 cls.webserver1_public_ip))
656
657 # Create webserver 2 instance
658 server_details = cls._create_webserver('lb_member_webserver2',
659 cls.lb_member_2_net)
660
661 cls.lb_member_webserver2 = server_details['server']
662 cls.webserver2_ip = server_details.get('ipv4_address')
663 cls.webserver2_ipv6 = server_details.get('ipv6_address')
664 cls.webserver2_public_ip = server_details['public_ipv4_address']
665
666 LOG.debug('Octavia Setup: lb_member_webserver2 = {}'.format(
667 cls.lb_member_webserver2[const.ID]))
668 LOG.debug('Octavia Setup: webserver2_ip = {}'.format(
669 cls.webserver2_ip))
670 LOG.debug('Octavia Setup: webserver2_ipv6 = {}'.format(
671 cls.webserver2_ipv6))
672 LOG.debug('Octavia Setup: webserver2_public_ip = {}'.format(
673 cls.webserver2_public_ip))
674
Michael Johnsonbf916df2018-10-17 10:59:28 -0700675 if CONF.load_balancer.test_with_ipv6:
676 # Enable the IPv6 nic in webserver 1
677 cls._enable_ipv6_nic_webserver(
678 cls.webserver1_public_ip, cls.lb_member_keypair['private_key'],
679 cls.webserver1_ipv6, cls.lb_member_1_subnet_prefix)
680
681 # Enable the IPv6 nic in webserver 2
682 cls._enable_ipv6_nic_webserver(
683 cls.webserver2_public_ip, cls.lb_member_keypair['private_key'],
684 cls.webserver2_ipv6, cls.lb_member_2_subnet_prefix)
685
Adam Harwellcd72b562018-05-07 11:37:22 -0700686 # Set up serving on webserver 1
687 cls._install_start_webserver(cls.webserver1_public_ip,
Adam Harwelle029af22018-05-24 17:13:28 -0700688 cls.lb_member_keypair['private_key'],
689 cls.webserver1_response)
Adam Harwellcd72b562018-05-07 11:37:22 -0700690
691 # Validate webserver 1
Adam Harwelle029af22018-05-24 17:13:28 -0700692 cls._validate_webserver(cls.webserver1_public_ip,
693 cls.webserver1_response)
Adam Harwellcd72b562018-05-07 11:37:22 -0700694
Gregory Thiemonge29d17902019-04-30 15:06:17 +0200695 # Validate udp server 1
696 cls._validate_udp_server(cls.webserver1_public_ip,
697 cls.webserver1_response)
698
Adam Harwellcd72b562018-05-07 11:37:22 -0700699 # Set up serving on webserver 2
700 cls._install_start_webserver(cls.webserver2_public_ip,
Adam Harwelle029af22018-05-24 17:13:28 -0700701 cls.lb_member_keypair['private_key'],
702 cls.webserver2_response)
Adam Harwellcd72b562018-05-07 11:37:22 -0700703
704 # Validate webserver 2
Adam Harwelle029af22018-05-24 17:13:28 -0700705 cls._validate_webserver(cls.webserver2_public_ip,
706 cls.webserver2_response)
Adam Harwellcd72b562018-05-07 11:37:22 -0700707
Gregory Thiemonge29d17902019-04-30 15:06:17 +0200708 # Validate udp server 2
709 cls._validate_udp_server(cls.webserver2_public_ip,
710 cls.webserver2_response)
711
Adam Harwellcd72b562018-05-07 11:37:22 -0700712 @classmethod
713 def _create_networks(cls):
714 super(LoadBalancerBaseTestWithCompute, cls)._create_networks()
Jude Cross986e3f52017-07-24 14:57:20 -0700715 # Create a router for the subnets (required for the floating IP)
716 router_name = data_utils.rand_name("lb_member_router")
717 result = cls.lb_mem_routers_client.create_router(
718 name=router_name, admin_state_up=True,
719 external_gateway_info=dict(
720 network_id=CONF.network.public_network_id))
721 cls.lb_member_router = result['router']
722 LOG.info('lb_member_router: {}'.format(cls.lb_member_router))
723 cls.addClassResourceCleanup(
724 waiters.wait_for_not_found,
725 cls.lb_mem_routers_client.delete_router,
726 cls.lb_mem_routers_client.show_router,
727 cls.lb_member_router['id'])
728
729 # Add VIP subnet to router
730 cls.lb_mem_routers_client.add_router_interface(
731 cls.lb_member_router['id'],
732 subnet_id=cls.lb_member_vip_subnet['id'])
733 cls.addClassResourceCleanup(
734 waiters.wait_for_not_found,
735 cls.lb_mem_routers_client.remove_router_interface,
736 cls.lb_mem_routers_client.remove_router_interface,
737 cls.lb_member_router['id'],
738 subnet_id=cls.lb_member_vip_subnet['id'])
739
740 # Add member subnet 1 to router
741 cls.lb_mem_routers_client.add_router_interface(
742 cls.lb_member_router['id'],
743 subnet_id=cls.lb_member_1_subnet['id'])
744 cls.addClassResourceCleanup(
745 waiters.wait_for_not_found,
Jude Cross986e3f52017-07-24 14:57:20 -0700746 cls.lb_mem_routers_client.remove_router_interface,
747 cls.lb_mem_routers_client.remove_router_interface,
748 cls.lb_member_router['id'], subnet_id=cls.lb_member_1_subnet['id'])
749
750 # Add member subnet 2 to router
751 cls.lb_mem_routers_client.add_router_interface(
752 cls.lb_member_router['id'],
753 subnet_id=cls.lb_member_2_subnet['id'])
754 cls.addClassResourceCleanup(
755 waiters.wait_for_not_found,
756 cls.lb_mem_routers_client.remove_router_interface,
757 cls.lb_mem_routers_client.remove_router_interface,
758 cls.lb_member_router['id'], subnet_id=cls.lb_member_2_subnet['id'])
759
760 @classmethod
761 def _create_webserver(cls, name, network):
762 """Creates a webserver with two ports.
763
764 webserver_details dictionary contains:
765 server - The compute server object
766 ipv4_address - The IPv4 address for the server (optional)
767 ipv6_address - The IPv6 address for the server (optional)
768 public_ipv4_address - The publicly accessible IPv4 address for the
769 server, this may be a floating IP (optional)
770
771 :param name: The name of the server to create.
772 :param network: The network to boot the server on.
773 :returns: webserver_details dictionary.
774 """
775 server_kwargs = {
776 'name': data_utils.rand_name(name),
777 'flavorRef': CONF.compute.flavor_ref,
778 'imageRef': CONF.compute.image_ref,
779 'key_name': cls.lb_member_keypair['name']}
780 if (CONF.load_balancer.enable_security_groups and
781 CONF.network_feature_enabled.port_security):
782 server_kwargs['security_groups'] = [
783 {'name': cls.lb_member_sec_group['name']}]
784 if not CONF.load_balancer.disable_boot_network:
785 server_kwargs['networks'] = [{'uuid': network['id']}]
786
787 # Replace the name for clouds that have limitations
788 if CONF.load_balancer.random_server_name_length:
789 r = random.SystemRandom()
790 server_kwargs['name'] = "m{}".format("".join(
791 [r.choice(string.ascii_uppercase + string.digits)
792 for _ in range(
793 CONF.load_balancer.random_server_name_length - 1)]
794 ))
795 if CONF.load_balancer.availability_zone:
796 server_kwargs['availability_zone'] = (
797 CONF.load_balancer.availability_zone)
798
799 server = cls.lb_mem_servers_client.create_server(
800 **server_kwargs)['server']
801 cls.addClassResourceCleanup(
802 waiters.wait_for_not_found,
803 cls.lb_mem_servers_client.delete_server,
804 cls.lb_mem_servers_client.show_server,
805 server['id'])
806 server = waiters.wait_for_status(
807 cls.lb_mem_servers_client.show_server,
808 server['id'], 'status', 'ACTIVE',
809 CONF.load_balancer.build_interval,
810 CONF.load_balancer.build_timeout,
811 root_tag='server')
812 webserver_details = {'server': server}
813 LOG.info('Created server: {}'.format(server))
814
815 addresses = server['addresses']
816 if CONF.load_balancer.disable_boot_network:
817 instance_network = addresses.values()[0]
818 else:
819 instance_network = addresses[network['name']]
820 for addr in instance_network:
821 if addr['version'] == 4:
822 webserver_details['ipv4_address'] = addr['addr']
823 if addr['version'] == 6:
824 webserver_details['ipv6_address'] = addr['addr']
825
826 if CONF.validation.connect_method == 'floating':
827 result = cls.lb_mem_ports_client.list_ports(
828 network_id=network['id'],
829 mac_address=instance_network[0]['OS-EXT-IPS-MAC:mac_addr'])
830 port_id = result['ports'][0]['id']
831 result = cls.lb_mem_float_ip_client.create_floatingip(
832 floating_network_id=CONF.network.public_network_id,
833 port_id=port_id)
834 floating_ip = result['floatingip']
835 LOG.info('webserver1_floating_ip: {}'.format(floating_ip))
836 cls.addClassResourceCleanup(
837 waiters.wait_for_not_found,
838 cls.lb_mem_float_ip_client.delete_floatingip,
839 cls.lb_mem_float_ip_client.show_floatingip,
840 floatingip_id=floating_ip['id'])
841 webserver_details['public_ipv4_address'] = (
842 floating_ip['floating_ip_address'])
843 else:
844 webserver_details['public_ipv4_address'] = (
845 instance_network[0]['addr'])
846
847 return webserver_details
848
849 @classmethod
Adam Harwellcd72b562018-05-07 11:37:22 -0700850 def _install_start_webserver(cls, ip_address, ssh_key, start_id):
851 local_file = pkg_resources.resource_filename(
Gregory Thiemonge29d17902019-04-30 15:06:17 +0200852 'octavia_tempest_plugin.contrib.test_server', 'test_server.bin')
853 dest_file = '/dev/shm/test_server.bin'
Adam Harwellcd72b562018-05-07 11:37:22 -0700854
855 linux_client = remote_client.RemoteClient(
856 ip_address, CONF.validation.image_ssh_user, pkey=ssh_key)
857 linux_client.validate_authentication()
858
859 with tempfile.NamedTemporaryFile() as key:
860 key.write(ssh_key.encode('utf-8'))
861 key.flush()
862 cmd = ("scp -v -o UserKnownHostsFile=/dev/null "
863 "-o StrictHostKeyChecking=no "
864 "-o ConnectTimeout={0} -o ConnectionAttempts={1} "
865 "-i {2} {3} {4}@{5}:{6}").format(
866 CONF.load_balancer.scp_connection_timeout,
867 CONF.load_balancer.scp_connection_attempts,
868 key.name, local_file, CONF.validation.image_ssh_user,
869 ip_address, dest_file)
870 args = shlex.split(cmd)
871 subprocess_args = {'stdout': subprocess.PIPE,
872 'stderr': subprocess.STDOUT,
873 'cwd': None}
874 proc = subprocess.Popen(args, **subprocess_args)
875 stdout, stderr = proc.communicate()
876 if proc.returncode != 0:
877 raise exceptions.CommandFailed(proc.returncode, cmd,
878 stdout, stderr)
Gregory Thiemongef72a8862019-08-06 17:25:42 +0200879
880 # Enabling memory overcommit allows to run golang static binaries
881 # compiled with a recent golang toolchain (>=1.11). Those binaries
882 # allocate a large amount of virtual memory at init time, and this
883 # allocation fails in tempest's nano flavor (64MB of RAM)
884 # (golang issue reported in https://github.com/golang/go/issues/28114,
885 # follow-up: https://github.com/golang/go/issues/28081)
886 # TODO(gthiemonge): Remove this call when golang issue is resolved.
887 linux_client.exec_command('sudo sh -c "echo 1 > '
888 '/proc/sys/vm/overcommit_memory"')
889
Adam Harwellcd72b562018-05-07 11:37:22 -0700890 linux_client.exec_command('sudo screen -d -m {0} -port 80 '
891 '-id {1}'.format(dest_file, start_id))
892 linux_client.exec_command('sudo screen -d -m {0} -port 81 '
893 '-id {1}'.format(dest_file, start_id + 1))
894
Michael Johnsonbf916df2018-10-17 10:59:28 -0700895 # Cirros does not configure the assigned IPv6 address by default
896 # so enable it manually like tempest does here:
897 # tempest/scenario/test_netowrk_v6.py turn_nic6_on()
898 @classmethod
899 def _enable_ipv6_nic_webserver(cls, ip_address, ssh_key,
900 ipv6_address, ipv6_prefix):
901 linux_client = remote_client.RemoteClient(
902 ip_address, CONF.validation.image_ssh_user, pkey=ssh_key)
903 linux_client.validate_authentication()
904
905 linux_client.exec_command('sudo ip address add {0}/{1} dev '
906 'eth0'.format(ipv6_address, ipv6_prefix))
907
Adam Harwellcd72b562018-05-07 11:37:22 -0700908 @classmethod
Jude Cross986e3f52017-07-24 14:57:20 -0700909 def _validate_webserver(cls, ip_address, start_id):
910 URL = 'http://{0}'.format(ip_address)
Michael Johnson89bdbcd2020-03-19 15:59:19 -0700911 cls.validate_URL_response(URL, expected_body=str(start_id))
Jude Cross986e3f52017-07-24 14:57:20 -0700912 URL = 'http://{0}:81'.format(ip_address)
Michael Johnson89bdbcd2020-03-19 15:59:19 -0700913 cls.validate_URL_response(URL, expected_body=str(start_id + 1))
Jude Cross986e3f52017-07-24 14:57:20 -0700914
Gregory Thiemonge29d17902019-04-30 15:06:17 +0200915 @classmethod
916 def _validate_udp_server(cls, ip_address, start_id):
Michael Johnson89bdbcd2020-03-19 15:59:19 -0700917 res = cls.make_udp_request(ip_address, 80)
Gregory Thiemonge29d17902019-04-30 15:06:17 +0200918 if res != str(start_id):
919 raise Exception("Response from test server doesn't match the "
920 "expected value ({0} != {1}).".format(
921 res, str(start_id)))
922
Michael Johnson89bdbcd2020-03-19 15:59:19 -0700923 res = cls.make_udp_request(ip_address, 81)
Gregory Thiemonge29d17902019-04-30 15:06:17 +0200924 if res != str(start_id + 1):
925 raise Exception("Response from test server doesn't match the "
926 "expected value ({0} != {1}).".format(
927 res, str(start_id + 1)))