blob: af7b68388a8113845aa623487767b45d3fff093e [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
Gavin Brebner0f465a32013-03-14 13:26:09 +00002# Copyright 2013 Hewlett-Packard Development Company, L.P.
Maru Newby81f07a02012-09-05 20:21:19 -07003# All Rights Reserved.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
Yair Fried2d2f3fe2014-02-24 16:19:20 +020016import collections
Yair Fried3097dc12014-01-26 08:46:43 +020017import re
Matthew Treinish96e9e882014-06-09 18:37:19 -040018
Doug Hellmann583ce2c2015-03-11 14:55:46 +000019from oslo_log import log as logging
Matthew Treinish01472ff2015-02-20 17:26:52 -050020from tempest_lib.common.utils import data_utils
Adam Gandelman7186f7a2014-07-23 09:28:56 -040021import testtools
Yair Fried3097dc12014-01-26 08:46:43 +020022
Matthew Treinishcb569942013-08-09 16:33:44 -040023from tempest import config
Attila Fazekasa8bb3942014-08-19 09:06:30 +020024from tempest import exceptions
Sean Dague6dbc6da2013-05-08 17:49:46 -040025from tempest.scenario import manager
Yair Fried1fc32a12014-08-04 09:11:30 +030026from tempest.services.network import resources as net_resources
Yoshihiro Kaneko05670262014-01-18 19:22:44 +090027from tempest import test
Maru Newby81f07a02012-09-05 20:21:19 -070028
Sean Dague86bd8422013-12-20 09:56:44 -050029CONF = config.CONF
Matthew Treinish2b59f842013-09-09 20:32:51 +000030LOG = logging.getLogger(__name__)
31
Yair Fried2d2f3fe2014-02-24 16:19:20 +020032Floating_IP_tuple = collections.namedtuple('Floating_IP_tuple',
33 ['floating_ip', 'server'])
34
Maru Newby81f07a02012-09-05 20:21:19 -070035
Andrea Frittoli4971fc82014-09-25 10:22:20 +010036class TestNetworkBasicOps(manager.NetworkScenarioTest):
Maru Newby81f07a02012-09-05 20:21:19 -070037
38 """
39 This smoke test suite assumes that Nova has been configured to
Mark McClainf2982e82013-07-06 17:48:03 -040040 boot VM's with Neutron-managed networking, and attempts to
Maru Newby81f07a02012-09-05 20:21:19 -070041 verify network connectivity as follows:
42
Maru Newby81f07a02012-09-05 20:21:19 -070043 There are presumed to be two types of networks: tenant and
44 public. A tenant network may or may not be reachable from the
45 Tempest host. A public network is assumed to be reachable from
46 the Tempest host, and it should be possible to associate a public
47 ('floating') IP address with a tenant ('fixed') IP address to
Chang Bo Guocc1623c2013-09-13 20:11:27 -070048 facilitate external connectivity to a potentially unroutable
Maru Newby81f07a02012-09-05 20:21:19 -070049 tenant IP address.
50
51 This test suite can be configured to test network connectivity to
52 a VM via a tenant network, a public network, or both. If both
53 networking types are to be evaluated, tests that need to be
54 executed remotely on the VM (via ssh) will only be run against
55 one of the networks (to minimize test execution time).
56
57 Determine which types of networks to test as follows:
58
59 * Configure tenant network checks (via the
60 'tenant_networks_reachable' key) if the Tempest host should
61 have direct connectivity to tenant networks. This is likely to
62 be the case if Tempest is running on the same host as a
63 single-node devstack installation with IP namespaces disabled.
64
65 * Configure checks for a public network if a public network has
66 been configured prior to the test suite being run and if the
67 Tempest host should have connectivity to that public network.
68 Checking connectivity for a public network requires that a
69 value be provided for 'public_network_id'. A value can
70 optionally be provided for 'public_router_id' if tenants will
71 use a shared router to access a public network (as is likely to
72 be the case when IP namespaces are not enabled). If a value is
73 not provided for 'public_router_id', a router will be created
74 for each tenant and use the network identified by
75 'public_network_id' as its gateway.
76
77 """
78
79 @classmethod
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +000080 def skip_checks(cls):
81 super(TestNetworkBasicOps, cls).skip_checks()
Matthew Treinish6c072292014-01-29 19:15:52 +000082 if not (CONF.network.tenant_networks_reachable
83 or CONF.network.public_network_id):
Maru Newby81f07a02012-09-05 20:21:19 -070084 msg = ('Either tenant_networks_reachable must be "true", or '
85 'public_network_id must be defined.')
ivan-zhu1feeb382013-01-24 10:14:39 +080086 raise cls.skipException(msg)
Yoshihiro Kaneko05670262014-01-18 19:22:44 +090087 for ext in ['router', 'security-group']:
88 if not test.is_extension_enabled(ext, 'network'):
89 msg = "%s extension not enabled." % ext
90 raise cls.skipException(msg)
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +000091
92 @classmethod
93 def setup_credentials(cls):
Masayuki Igawa60ea6c52014-10-15 17:32:14 +090094 # Create no network resources for these tests.
95 cls.set_network_resources()
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +000096 super(TestNetworkBasicOps, cls).setup_credentials()
Maru Newby81f07a02012-09-05 20:21:19 -070097
Yair Frieded8392f2014-01-15 17:21:35 +020098 def setUp(self):
99 super(TestNetworkBasicOps, self).setUp()
Yair Fried1fc32a12014-08-04 09:11:30 +0300100 self.keypairs = {}
101 self.servers = []
David Shrewsbury9bac3662014-08-07 15:07:01 -0400102
Yair Fried413bf2d2014-11-19 17:07:11 +0200103 def _setup_network_and_servers(self, **kwargs):
David Shrewsbury9bac3662014-08-07 15:07:01 -0400104 self.security_group = \
105 self._create_security_group(tenant_id=self.tenant_id)
Yair Fried413bf2d2014-11-19 17:07:11 +0200106 self.network, self.subnet, self.router = self.create_networks(**kwargs)
David Shrewsbury9bac3662014-08-07 15:07:01 -0400107 self.check_networks()
108
Yair Frieded8392f2014-01-15 17:21:35 +0200109 name = data_utils.rand_name('server-smoke')
Andrea Frittoli8ec99fe2015-03-13 09:22:56 +0000110 server = self._create_server(name, self.network)
Yair Frieded8392f2014-01-15 17:21:35 +0200111 self._check_tenant_network_connectivity()
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200112
Yair Friedae0e73d2014-11-24 11:56:26 +0200113 floating_ip = self.create_floating_ip(server)
114 self.floating_ip_tuple = Floating_IP_tuple(floating_ip, server)
Maru Newby81f07a02012-09-05 20:21:19 -0700115
Yair Frieded8392f2014-01-15 17:21:35 +0200116 def check_networks(self):
117 """
118 Checks that we see the newly created network/subnet/router via
119 checking the result of list_[networks,routers,subnets]
120 """
121
Gavin Brebner851c3502013-01-18 13:14:10 +0000122 seen_nets = self._list_networks()
123 seen_names = [n['name'] for n in seen_nets]
124 seen_ids = [n['id'] for n in seen_nets]
Yair Frieded8392f2014-01-15 17:21:35 +0200125 self.assertIn(self.network.name, seen_names)
126 self.assertIn(self.network.id, seen_ids)
127
David Shrewsbury9bac3662014-08-07 15:07:01 -0400128 if self.subnet:
129 seen_subnets = self._list_subnets()
130 seen_net_ids = [n['network_id'] for n in seen_subnets]
131 seen_subnet_ids = [n['id'] for n in seen_subnets]
132 self.assertIn(self.network.id, seen_net_ids)
133 self.assertIn(self.subnet.id, seen_subnet_ids)
Yair Frieded8392f2014-01-15 17:21:35 +0200134
David Shrewsbury9bac3662014-08-07 15:07:01 -0400135 if self.router:
136 seen_routers = self._list_routers()
137 seen_router_ids = [n['id'] for n in seen_routers]
138 seen_router_names = [n['name'] for n in seen_routers]
139 self.assertIn(self.router.name,
140 seen_router_names)
141 self.assertIn(self.router.id,
142 seen_router_ids)
Gavin Brebner851c3502013-01-18 13:14:10 +0000143
Andrea Frittoli8ec99fe2015-03-13 09:22:56 +0000144 def _create_server(self, name, network):
Yair Fried1fc32a12014-08-04 09:11:30 +0300145 keypair = self.create_keypair()
146 self.keypairs[keypair['name']] = keypair
Ken'ichi Ohmichi1b3461e2014-12-02 03:41:07 +0000147 security_groups = [{'name': self.security_group['name']}]
Salvatore Orlando5ed3b6e2013-09-17 01:27:26 -0700148 create_kwargs = {
Dirk Mueller8cf79722014-09-12 17:37:15 +0200149 'networks': [
150 {'uuid': network.id},
Salvatore Orlando5ed3b6e2013-09-17 01:27:26 -0700151 ],
Yair Fried1fc32a12014-08-04 09:11:30 +0300152 'key_name': keypair['name'],
Salvatore Orlando5ed3b6e2013-09-17 01:27:26 -0700153 'security_groups': security_groups,
154 }
Giulio Fidente61cadca2013-09-24 18:33:37 +0200155 server = self.create_server(name=name, create_kwargs=create_kwargs)
Yair Fried1fc32a12014-08-04 09:11:30 +0300156 self.servers.append(server)
157 return server
158
159 def _get_server_key(self, server):
160 return self.keypairs[server['key_name']]['private_key']
Salvatore Orlando5ed3b6e2013-09-17 01:27:26 -0700161
Matthew Treinish2b59f842013-09-09 20:32:51 +0000162 def _check_tenant_network_connectivity(self):
Sean Dague86bd8422013-12-20 09:56:44 -0500163 ssh_login = CONF.compute.image_ssh_user
Yair Fried1fc32a12014-08-04 09:11:30 +0300164 for server in self.servers:
Matt Riedemann2d005be2014-05-27 10:52:35 -0700165 # call the common method in the parent class
166 super(TestNetworkBasicOps, self).\
167 _check_tenant_network_connectivity(
Yair Fried1fc32a12014-08-04 09:11:30 +0300168 server, ssh_login, self._get_server_key(server),
169 servers_for_debug=self.servers)
Brent Eaglesc26d4522013-12-02 13:28:49 -0500170
Alok Maurya6384bbb2014-07-13 06:44:29 -0700171 def check_public_network_connectivity(
172 self, should_connect=True, msg=None,
173 should_check_floating_ip_status=True):
Yair Fried45f92952014-06-26 05:19:19 +0300174 """Verifies connectivty to a VM via public network and floating IP,
175 and verifies floating IP has resource status is correct.
176
Yair Fried45f92952014-06-26 05:19:19 +0300177 :param should_connect: bool. determines if connectivity check is
178 negative or positive.
179 :param msg: Failure message to add to Error message. Should describe
180 the place in the test scenario where the method was called,
181 to indicate the context of the failure
Alok Maurya6384bbb2014-07-13 06:44:29 -0700182 :param should_check_floating_ip_status: bool. should status of
183 floating_ip be checked or not
Yair Fried45f92952014-06-26 05:19:19 +0300184 """
Sean Dague86bd8422013-12-20 09:56:44 -0500185 ssh_login = CONF.compute.image_ssh_user
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200186 floating_ip, server = self.floating_ip_tuple
187 ip_address = floating_ip.floating_ip_address
188 private_key = None
Yair Fried45f92952014-06-26 05:19:19 +0300189 floatingip_status = 'DOWN'
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200190 if should_connect:
Yair Fried1fc32a12014-08-04 09:11:30 +0300191 private_key = self._get_server_key(server)
Yair Fried45f92952014-06-26 05:19:19 +0300192 floatingip_status = 'ACTIVE'
Swaminathan Vasudevandc8bcdb2015-02-28 12:47:21 -0800193 # Check FloatingIP Status before initiating a connection
194 if should_check_floating_ip_status:
195 self.check_floating_ip_status(floating_ip, floatingip_status)
Matt Riedemann343305f2014-05-27 09:55:03 -0700196 # call the common method in the parent class
Yair Friedae0e73d2014-11-24 11:56:26 +0200197 super(TestNetworkBasicOps, self).check_public_network_connectivity(
Matt Riedemann343305f2014-05-27 09:55:03 -0700198 ip_address, ssh_login, private_key, should_connect, msg,
Yair Fried1fc32a12014-08-04 09:11:30 +0300199 self.servers)
Matthew Treinish2b59f842013-09-09 20:32:51 +0000200
Yair Fried9a551c42013-12-15 14:59:34 +0200201 def _disassociate_floating_ips(self):
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200202 floating_ip, server = self.floating_ip_tuple
203 self._disassociate_floating_ip(floating_ip)
204 self.floating_ip_tuple = Floating_IP_tuple(
205 floating_ip, None)
Yair Fried9a551c42013-12-15 14:59:34 +0200206
Yair Fried05db2522013-11-18 11:02:10 +0200207 def _reassociate_floating_ips(self):
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200208 floating_ip, server = self.floating_ip_tuple
209 name = data_utils.rand_name('new_server-smoke-')
210 # create a new server for the floating ip
Yair Fried1fc32a12014-08-04 09:11:30 +0300211 server = self._create_server(name, self.network)
212 self._associate_floating_ip(floating_ip, server)
Yair Fried2d2f3fe2014-02-24 16:19:20 +0200213 self.floating_ip_tuple = Floating_IP_tuple(
Yair Fried1fc32a12014-08-04 09:11:30 +0300214 floating_ip, server)
Yair Fried05db2522013-11-18 11:02:10 +0200215
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300216 def _create_new_network(self, create_gateway=False):
Yair Frieddb6c9e92014-08-06 08:53:13 +0300217 self.new_net = self._create_network(tenant_id=self.tenant_id)
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300218 if create_gateway:
219 self.new_subnet = self._create_subnet(
220 network=self.new_net)
221 else:
222 self.new_subnet = self._create_subnet(
223 network=self.new_net,
224 gateway_ip=None)
Yair Fried3097dc12014-01-26 08:46:43 +0200225
226 def _hotplug_server(self):
227 old_floating_ip, server = self.floating_ip_tuple
228 ip_address = old_floating_ip.floating_ip_address
Yair Fried1fc32a12014-08-04 09:11:30 +0300229 private_key = self._get_server_key(server)
Yair Fried3097dc12014-01-26 08:46:43 +0200230 ssh_client = self.get_remote_client(ip_address,
231 private_key=private_key)
232 old_nic_list = self._get_server_nics(ssh_client)
233 # get a port from a list of one item
Yair Fried1fc32a12014-08-04 09:11:30 +0300234 port_list = self._list_ports(device_id=server['id'])
Yair Fried3097dc12014-01-26 08:46:43 +0200235 self.assertEqual(1, len(port_list))
236 old_port = port_list[0]
David Kranzb2b0c182015-02-18 13:28:19 -0500237 interface = self.interface_client.create_interface(
Yair Fried1fc32a12014-08-04 09:11:30 +0300238 server=server['id'],
239 network_id=self.new_net.id)
240 self.addCleanup(self.network_client.wait_for_resource_deletion,
241 'port',
242 interface['port_id'])
243 self.addCleanup(self.delete_wrapper,
244 self.interface_client.delete_interface,
245 server['id'], interface['port_id'])
Yair Fried3097dc12014-01-26 08:46:43 +0200246
247 def check_ports():
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200248 self.new_port_list = [port for port in
Yair Fried1fc32a12014-08-04 09:11:30 +0300249 self._list_ports(device_id=server['id'])
armando-migliaccio3820a062015-02-12 19:31:54 -0800250 if port['id'] != old_port['id']]
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200251 return len(self.new_port_list) == 1
Yair Fried3097dc12014-01-26 08:46:43 +0200252
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200253 if not test.call_until_true(check_ports, CONF.network.build_timeout,
254 CONF.network.build_interval):
Matt Riedemann892094e2015-02-05 07:24:02 -0800255 raise exceptions.TimeoutException(
256 "No new port attached to the server in time (%s sec)! "
257 "Old port: %s. Number of new ports: %d" % (
258 CONF.network.build_timeout, old_port,
259 len(self.new_port_list)))
Yair Fried1fc32a12014-08-04 09:11:30 +0300260 new_port = net_resources.DeletablePort(client=self.network_client,
261 **self.new_port_list[0])
Attila Fazekasa8bb3942014-08-19 09:06:30 +0200262
263 def check_new_nic():
264 new_nic_list = self._get_server_nics(ssh_client)
265 self.diff_list = [n for n in new_nic_list if n not in old_nic_list]
266 return len(self.diff_list) == 1
267
268 if not test.call_until_true(check_new_nic, CONF.network.build_timeout,
269 CONF.network.build_interval):
270 raise exceptions.TimeoutException("Interface not visible on the "
271 "guest after %s sec"
272 % CONF.network.build_timeout)
273
274 num, new_nic = self.diff_list[0]
Yair Fried3097dc12014-01-26 08:46:43 +0200275 ssh_client.assign_static_ip(nic=new_nic,
276 addr=new_port.fixed_ips[0]['ip_address'])
277 ssh_client.turn_nic_on(nic=new_nic)
278
279 def _get_server_nics(self, ssh_client):
280 reg = re.compile(r'(?P<num>\d+): (?P<nic_name>\w+):')
281 ipatxt = ssh_client.get_ip_list()
282 return reg.findall(ipatxt)
283
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300284 def _check_network_internal_connectivity(self, network,
285 should_connect=True):
Yair Fried3097dc12014-01-26 08:46:43 +0200286 """
287 via ssh check VM internal connectivity:
Yair Fried06552292013-11-11 12:10:09 +0200288 - ping internal gateway and DHCP port, implying in-tenant connectivity
289 pinging both, because L3 and DHCP agents might be on different nodes
Yair Fried3097dc12014-01-26 08:46:43 +0200290 """
291 floating_ip, server = self.floating_ip_tuple
292 # get internal ports' ips:
293 # get all network ports in the new network
294 internal_ips = (p['fixed_ips'][0]['ip_address'] for p in
Yair Fried1fc32a12014-08-04 09:11:30 +0300295 self._list_ports(tenant_id=server['tenant_id'],
Yair Fried06552292013-11-11 12:10:09 +0200296 network_id=network.id)
Yair Fried3097dc12014-01-26 08:46:43 +0200297 if p['device_owner'].startswith('network'))
298
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300299 self._check_server_connectivity(floating_ip,
300 internal_ips,
301 should_connect)
Yair Fried06552292013-11-11 12:10:09 +0200302
303 def _check_network_external_connectivity(self):
304 """
305 ping public network default gateway to imply external connectivity
306
307 """
308 if not CONF.network.public_network_id:
309 msg = 'public network not defined.'
310 LOG.info(msg)
311 return
312
Yair Fried1fc32a12014-08-04 09:11:30 +0300313 subnet = self._list_subnets(
314 network_id=CONF.network.public_network_id)
Yair Fried06552292013-11-11 12:10:09 +0200315 self.assertEqual(1, len(subnet), "Found %d subnets" % len(subnet))
316
317 external_ips = [subnet[0]['gateway_ip']]
318 self._check_server_connectivity(self.floating_ip_tuple.floating_ip,
319 external_ips)
320
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300321 def _check_server_connectivity(self, floating_ip, address_list,
322 should_connect=True):
Yair Fried3097dc12014-01-26 08:46:43 +0200323 ip_address = floating_ip.floating_ip_address
Yair Fried1fc32a12014-08-04 09:11:30 +0300324 private_key = self._get_server_key(self.floating_ip_tuple.server)
Yair Fried3097dc12014-01-26 08:46:43 +0200325 ssh_source = self._ssh_to_server(ip_address, private_key)
326
Yair Fried06552292013-11-11 12:10:09 +0200327 for remote_ip in address_list:
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300328 if should_connect:
329 msg = "Timed out waiting for "
330 "%s to become reachable" % remote_ip
331 else:
332 msg = "ip address %s is reachable" % remote_ip
Yair Fried3097dc12014-01-26 08:46:43 +0200333 try:
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300334 self.assertTrue(self._check_remote_connectivity
335 (ssh_source, remote_ip, should_connect),
336 msg)
Yair Fried3097dc12014-01-26 08:46:43 +0200337 except Exception:
338 LOG.exception("Unable to access {dest} via ssh to "
339 "floating-ip {src}".format(dest=remote_ip,
340 src=floating_ip))
Yair Fried3097dc12014-01-26 08:46:43 +0200341 raise
342
Yoshihiro Kaneko05670262014-01-18 19:22:44 +0900343 @test.attr(type='smoke')
Chris Hoge7579c1a2015-02-26 14:12:15 -0800344 @test.idempotent_id('f323b3ba-82f8-4db7-8ea6-6a895869ec49')
Yoshihiro Kaneko05670262014-01-18 19:22:44 +0900345 @test.services('compute', 'network')
Matthew Treinish2b59f842013-09-09 20:32:51 +0000346 def test_network_basic_ops(self):
Yair Fried3097dc12014-01-26 08:46:43 +0200347 """
348 For a freshly-booted VM with an IP address ("port") on a given
349 network:
350
351 - the Tempest host can ping the IP address. This implies, but
352 does not guarantee (see the ssh check that follows), that the
353 VM has been assigned the correct IP address and has
354 connectivity to the Tempest host.
355
356 - the Tempest host can perform key-based authentication to an
357 ssh server hosted at the IP address. This check guarantees
358 that the IP address is associated with the target VM.
359
Yair Fried3097dc12014-01-26 08:46:43 +0200360 - the Tempest host can ssh into the VM via the IP address and
361 successfully execute the following:
362
363 - ping an external IP address, implying external connectivity.
364
365 - ping an external hostname, implying that dns is correctly
366 configured.
367
368 - ping an internal IP address, implying connectivity to another
369 VM on the same network.
370
Yair Fried06552292013-11-11 12:10:09 +0200371 - detach the floating-ip from the VM and verify that it becomes
372 unreachable
373
374 - associate detached floating ip to a new VM and verify connectivity.
375 VMs are created with unique keypair so connectivity also asserts that
376 floating IP is associated with the new VM instead of the old one
377
Yair Fried45f92952014-06-26 05:19:19 +0300378 Verifies that floating IP status is updated correctly after each change
379
Yair Fried06552292013-11-11 12:10:09 +0200380
Yair Fried3097dc12014-01-26 08:46:43 +0200381 """
David Shrewsbury9bac3662014-08-07 15:07:01 -0400382 self._setup_network_and_servers()
Yair Friedae0e73d2014-11-24 11:56:26 +0200383 self.check_public_network_connectivity(should_connect=True)
Yair Fried06552292013-11-11 12:10:09 +0200384 self._check_network_internal_connectivity(network=self.network)
385 self._check_network_external_connectivity()
Yair Fried9a551c42013-12-15 14:59:34 +0200386 self._disassociate_floating_ips()
Yair Friedae0e73d2014-11-24 11:56:26 +0200387 self.check_public_network_connectivity(should_connect=False,
388 msg="after disassociate "
389 "floating ip")
Yair Fried05db2522013-11-18 11:02:10 +0200390 self._reassociate_floating_ips()
Yair Friedae0e73d2014-11-24 11:56:26 +0200391 self.check_public_network_connectivity(should_connect=True,
392 msg="after re-associate "
393 "floating ip")
Yair Fried3097dc12014-01-26 08:46:43 +0200394
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300395 @test.idempotent_id('1546850e-fbaa-42f5-8b5f-03d8a6a95f15')
Adam Gandelman36b71fc2015-03-12 12:24:08 -0700396 @testtools.skipIf(CONF.baremetal.driver_enabled,
397 'Baremetal relies on a shared physical network.')
Fei Long Wang05a1c4a2015-02-02 16:58:24 +1300398 @test.attr(type='smoke')
399 @test.services('compute', 'network')
400 def test_connectivity_between_vms_on_different_networks(self):
401 """
402 For a freshly-booted VM with an IP address ("port") on a given
403 network:
404
405 - the Tempest host can ping the IP address.
406
407 - the Tempest host can ssh into the VM via the IP address and
408 successfully execute the following:
409
410 - ping an external IP address, implying external connectivity.
411
412 - ping an external hostname, implying that dns is correctly
413 configured.
414
415 - ping an internal IP address, implying connectivity to another
416 VM on the same network.
417
418 - Create another network on the same tenant with subnet, create
419 an VM on the new network.
420
421 - Ping the new VM from previous VM failed since the new network
422 was not attached to router yet.
423
424 - Attach the new network to the router, Ping the new VM from
425 previous VM succeed.
426
427 """
428 self._setup_network_and_servers()
429 self.check_public_network_connectivity(should_connect=True)
430 self._check_network_internal_connectivity(network=self.network)
431 self._check_network_external_connectivity()
432 self._create_new_network(create_gateway=True)
433 name = data_utils.rand_name('server-smoke')
434 self._create_server(name, self.new_net)
435 self._check_network_internal_connectivity(network=self.new_net,
436 should_connect=False)
437 self.new_subnet.add_to_router(self.router.id)
438 self._check_network_internal_connectivity(network=self.new_net,
439 should_connect=True)
440
Chris Hoge7579c1a2015-02-26 14:12:15 -0800441 @test.idempotent_id('c5adff73-e961-41f1-b4a9-343614f18cfa')
Adam Gandelman7186f7a2014-07-23 09:28:56 -0400442 @testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
443 'NIC hotplug not available')
Itzik Brown2ca01cd2014-12-08 12:58:20 +0200444 @testtools.skipIf(CONF.network.port_vnic_type in ['direct', 'macvtap'],
445 'NIC hotplug not supported for '
446 'vnic_type direct or macvtap')
Yair Fried3097dc12014-01-26 08:46:43 +0200447 @test.attr(type='smoke')
448 @test.services('compute', 'network')
449 def test_hotplug_nic(self):
450 """
451 1. create a new network, with no gateway (to prevent overwriting VM's
452 gateway)
453 2. connect VM to new network
454 3. set static ip and bring new nic up
455 4. check VM can ping new network dhcp port
456
457 """
David Shrewsbury9bac3662014-08-07 15:07:01 -0400458 self._setup_network_and_servers()
Yair Friedae0e73d2014-11-24 11:56:26 +0200459 self.check_public_network_connectivity(should_connect=True)
Yair Fried3097dc12014-01-26 08:46:43 +0200460 self._create_new_network()
461 self._hotplug_server()
Yair Fried06552292013-11-11 12:10:09 +0200462 self._check_network_internal_connectivity(network=self.new_net)
Alok Maurya6384bbb2014-07-13 06:44:29 -0700463
Chris Hoge7579c1a2015-02-26 14:12:15 -0800464 @test.idempotent_id('04b9fe4e-85e8-4aea-b937-ea93885ac59f')
Adam Gandelmancf611212014-12-09 14:13:28 -0800465 @testtools.skipIf(CONF.baremetal.driver_enabled,
466 'Router state cannot be altered on a shared baremetal '
467 'network')
Alok Maurya6384bbb2014-07-13 06:44:29 -0700468 @test.attr(type='smoke')
469 @test.services('compute', 'network')
470 def test_update_router_admin_state(self):
471 """
472 1. Check public connectivity before updating
473 admin_state_up attribute of router to False
474 2. Check public connectivity after updating
475 admin_state_up attribute of router to False
476 3. Check public connectivity after updating
477 admin_state_up attribute of router to True
478 """
479 self._setup_network_and_servers()
480 self.check_public_network_connectivity(
481 should_connect=True, msg="before updating "
482 "admin_state_up of router to False")
483 self._update_router_admin_state(self.router, False)
484 # TODO(alokmaurya): Remove should_check_floating_ip_status=False check
485 # once bug 1396310 is fixed
486
487 self.check_public_network_connectivity(
488 should_connect=False, msg="after updating "
489 "admin_state_up of router to False",
490 should_check_floating_ip_status=False)
491 self._update_router_admin_state(self.router, True)
492 self.check_public_network_connectivity(
493 should_connect=True, msg="after updating "
494 "admin_state_up of router to True")
Yair Fried413bf2d2014-11-19 17:07:11 +0200495
Chris Hoge7579c1a2015-02-26 14:12:15 -0800496 @test.idempotent_id('d8bb918e-e2df-48b2-97cd-b73c95450980')
Adam Gandelman40371682015-03-03 11:27:03 -0800497 @testtools.skipIf(CONF.baremetal.driver_enabled,
498 'network isolation not available for baremetal nodes')
Yair Fried413bf2d2014-11-19 17:07:11 +0200499 @testtools.skipUnless(CONF.scenario.dhcp_client,
500 "DHCP client is not available.")
501 @test.attr(type='smoke')
502 @test.services('compute', 'network')
503 def test_subnet_details(self):
504 """Tests that subnet's extra configuration details are affecting
Adam Gandelman40371682015-03-03 11:27:03 -0800505 the VMs. This test relies on non-shared, isolated tenant networks.
Yair Fried413bf2d2014-11-19 17:07:11 +0200506
507 NOTE: Neutron subnets push data to servers via dhcp-agent, so any
508 update in subnet requires server to actively renew its DHCP lease.
509
510 1. Configure subnet with dns nameserver
511 2. retrieve the VM's configured dns and verify it matches the one
512 configured for the subnet.
513 3. update subnet's dns
514 4. retrieve the VM's configured dns and verify it matches the new one
515 configured for the subnet.
516
517 TODO(yfried): add host_routes
518
519 any resolution check would be testing either:
520 * l3 forwarding (tested in test_network_basic_ops)
521 * Name resolution of an external DNS nameserver - out of scope for
522 Tempest
523 """
524 # this test check only updates (no actual resolution) so using
525 # arbitrary ip addresses as nameservers, instead of parsing CONF
526 initial_dns_server = '1.2.3.4'
527 alt_dns_server = '9.8.7.6'
Yair Friedbb0ea392015-01-19 07:26:08 +0000528
529 # renewal should be immediate.
530 # Timeouts are suggested by salvatore-orlando in
531 # https://bugs.launchpad.net/neutron/+bug/1412325/comments/3
532 renew_delay = CONF.network.build_interval
533 renew_timeout = CONF.network.build_timeout
534
Yair Fried413bf2d2014-11-19 17:07:11 +0200535 self._setup_network_and_servers(dns_nameservers=[initial_dns_server])
536 self.check_public_network_connectivity(should_connect=True)
537
538 floating_ip, server = self.floating_ip_tuple
539 ip_address = floating_ip.floating_ip_address
540 private_key = self._get_server_key(server)
541 ssh_client = self._ssh_to_server(ip_address, private_key)
542
armando-migliaccio424aa412015-02-22 17:55:17 -0800543 dns_servers = [initial_dns_server]
544 servers = ssh_client.get_dns_servers()
545 self.assertEqual(set(dns_servers), set(servers),
546 'Looking for servers: {trgt_serv}. '
547 'Retrieved DNS nameservers: {act_serv} '
548 'From host: {host}.'
549 .format(host=ssh_client.ssh_client.host,
550 act_serv=servers,
551 trgt_serv=dns_servers))
Yair Fried413bf2d2014-11-19 17:07:11 +0200552
553 self.subnet.update(dns_nameservers=[alt_dns_server])
554 # asserts that Neutron DB has updated the nameservers
555 self.assertEqual([alt_dns_server], self.subnet.dns_nameservers,
556 "Failed to update subnet's nameservers")
557
Yair Friedbb0ea392015-01-19 07:26:08 +0000558 def check_new_dns_server():
559 """Server needs to renew its dhcp lease in order to get the new dns
560 definitions from subnet
561 NOTE(amuller): we are renewing the lease as part of the retry
562 because Neutron updates dnsmasq asynchronously after the
563 subnet-update API call returns.
564 """
565 ssh_client.renew_lease(fixed_ip=floating_ip['fixed_ip_address'])
armando-migliaccio424aa412015-02-22 17:55:17 -0800566 if ssh_client.get_dns_servers() != [alt_dns_server]:
Yair Friedbb0ea392015-01-19 07:26:08 +0000567 LOG.debug("Failed to update DNS nameservers")
568 return False
569 return True
570
571 self.assertTrue(test.call_until_true(check_new_dns_server,
572 renew_timeout,
573 renew_delay),
574 msg="DHCP renewal failed to fetch "
575 "new DNS nameservers")
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800576
Chris Hoge7579c1a2015-02-26 14:12:15 -0800577 @test.idempotent_id('f5dfcc22-45fd-409f-954c-5bd500d7890b')
Adam Gandelman0a7948e2015-02-16 15:13:50 -0800578 @testtools.skipIf(CONF.baremetal.driver_enabled,
579 'admin_state of instance ports cannot be altered '
580 'for baremetal nodes')
Thalabathy Venkatesan76553d82015-01-07 22:54:39 -0800581 @test.attr(type='smoke')
582 @test.services('compute', 'network')
583 def test_update_instance_port_admin_state(self):
584 """
585 1. Check public connectivity before updating
586 admin_state_up attribute of instance port to False
587 2. Check public connectivity after updating
588 admin_state_up attribute of instance port to False
589 3. Check public connectivity after updating
590 admin_state_up attribute of instance port to True
591 """
592 self._setup_network_and_servers()
593 floating_ip, server = self.floating_ip_tuple
594 server_id = server['id']
595 port_id = self._list_ports(device_id=server_id)[0]['id']
596 self.check_public_network_connectivity(
597 should_connect=True, msg="before updating "
598 "admin_state_up of instance port to False")
599 self.network_client.update_port(port_id, admin_state_up=False)
600 self.check_public_network_connectivity(
601 should_connect=False, msg="after updating "
602 "admin_state_up of instance port to False",
603 should_check_floating_ip_status=False)
604 self.network_client.update_port(port_id, admin_state_up=True)
605 self.check_public_network_connectivity(
606 should_connect=True, msg="after updating "
607 "admin_state_up of instance port to True")