blob: 5a91d3697c2c30af6c18f5e0dab045591eb6ff27 [file] [log] [blame]
Maru Newby81f07a02012-09-05 20:21:19 -07001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2012 OpenStack, LLC
Gavin Brebner0f465a32013-03-14 13:26:09 +00004# Copyright 2013 Hewlett-Packard Development Company, L.P.
Maru Newby81f07a02012-09-05 20:21:19 -07005# All Rights Reserved.
6#
7# Licensed under the Apache License, Version 2.0 (the "License"); you may
8# not use this file except in compliance with the License. You may obtain
9# a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16# License for the specific language governing permissions and limitations
17# under the License.
18
Sean Dague1937d092013-05-17 16:36:38 -040019from tempest.api.network import common as net_common
Maru Newby81f07a02012-09-05 20:21:19 -070020from tempest.common.utils.data_utils import rand_name
Matthew Treinishcb569942013-08-09 16:33:44 -040021from tempest import config
Sean Dague6dbc6da2013-05-08 17:49:46 -040022from tempest.scenario import manager
Maru Newbybd360222013-04-08 22:48:50 +000023from tempest.test import attr
Maru Newby81f07a02012-09-05 20:21:19 -070024
25
Sean Dague6dbc6da2013-05-08 17:49:46 -040026class TestNetworkBasicOps(manager.NetworkScenarioTest):
Maru Newby81f07a02012-09-05 20:21:19 -070027
28 """
29 This smoke test suite assumes that Nova has been configured to
Mark McClainf2982e82013-07-06 17:48:03 -040030 boot VM's with Neutron-managed networking, and attempts to
Maru Newby81f07a02012-09-05 20:21:19 -070031 verify network connectivity as follows:
32
33 * For a freshly-booted VM with an IP address ("port") on a given network:
34
Maru Newbyaf292e82013-05-20 21:32:28 +000035 - the Tempest host can ping the IP address. This implies, but
36 does not guarantee (see the ssh check that follows), that the
37 VM has been assigned the correct IP address and has
Maru Newby81f07a02012-09-05 20:21:19 -070038 connectivity to the Tempest host.
39
Maru Newbyaf292e82013-05-20 21:32:28 +000040 - the Tempest host can perform key-based authentication to an
41 ssh server hosted at the IP address. This check guarantees
42 that the IP address is associated with the target VM.
43
Maru Newby81f07a02012-09-05 20:21:19 -070044 #TODO(mnewby) - Need to implement the following:
45 - the Tempest host can ssh into the VM via the IP address and
46 successfully execute the following:
47
48 - ping an external IP address, implying external connectivity.
49
50 - ping an external hostname, implying that dns is correctly
51 configured.
52
53 - ping an internal IP address, implying connectivity to another
54 VM on the same network.
55
56 There are presumed to be two types of networks: tenant and
57 public. A tenant network may or may not be reachable from the
58 Tempest host. A public network is assumed to be reachable from
59 the Tempest host, and it should be possible to associate a public
60 ('floating') IP address with a tenant ('fixed') IP address to
61 faciliate external connectivity to a potentially unroutable
62 tenant IP address.
63
64 This test suite can be configured to test network connectivity to
65 a VM via a tenant network, a public network, or both. If both
66 networking types are to be evaluated, tests that need to be
67 executed remotely on the VM (via ssh) will only be run against
68 one of the networks (to minimize test execution time).
69
70 Determine which types of networks to test as follows:
71
72 * Configure tenant network checks (via the
73 'tenant_networks_reachable' key) if the Tempest host should
74 have direct connectivity to tenant networks. This is likely to
75 be the case if Tempest is running on the same host as a
76 single-node devstack installation with IP namespaces disabled.
77
78 * Configure checks for a public network if a public network has
79 been configured prior to the test suite being run and if the
80 Tempest host should have connectivity to that public network.
81 Checking connectivity for a public network requires that a
82 value be provided for 'public_network_id'. A value can
83 optionally be provided for 'public_router_id' if tenants will
84 use a shared router to access a public network (as is likely to
85 be the case when IP namespaces are not enabled). If a value is
86 not provided for 'public_router_id', a router will be created
87 for each tenant and use the network identified by
88 'public_network_id' as its gateway.
89
90 """
91
Matthew Treinishcb569942013-08-09 16:33:44 -040092 CONF = config.TempestConfig()
93
Maru Newby81f07a02012-09-05 20:21:19 -070094 @classmethod
95 def check_preconditions(cls):
Gavin Brebner0f465a32013-03-14 13:26:09 +000096 super(TestNetworkBasicOps, cls).check_preconditions()
Maru Newby81f07a02012-09-05 20:21:19 -070097 cfg = cls.config.network
Maru Newby81f07a02012-09-05 20:21:19 -070098 if not (cfg.tenant_networks_reachable or cfg.public_network_id):
99 msg = ('Either tenant_networks_reachable must be "true", or '
100 'public_network_id must be defined.')
Gavin Brebner0f465a32013-03-14 13:26:09 +0000101 cls.enabled = False
ivan-zhu1feeb382013-01-24 10:14:39 +0800102 raise cls.skipException(msg)
Maru Newby81f07a02012-09-05 20:21:19 -0700103
104 @classmethod
105 def setUpClass(cls):
106 super(TestNetworkBasicOps, cls).setUpClass()
107 cls.check_preconditions()
Maru Newby81f07a02012-09-05 20:21:19 -0700108 cls.tenant_id = cls.manager._get_identity_client(
Gavin Brebnercb7faa32013-01-30 12:01:31 +0000109 cls.config.identity.username,
110 cls.config.identity.password,
111 cls.config.identity.tenant_name).tenant_id
Maru Newby81f07a02012-09-05 20:21:19 -0700112 # TODO(mnewby) Consider looking up entities as needed instead
113 # of storing them as collections on the class.
114 cls.keypairs = {}
115 cls.security_groups = {}
116 cls.networks = []
Gavin Brebner851c3502013-01-18 13:14:10 +0000117 cls.subnets = []
118 cls.routers = []
Maru Newby81f07a02012-09-05 20:21:19 -0700119 cls.servers = []
120 cls.floating_ips = {}
121
Maru Newby81f07a02012-09-05 20:21:19 -0700122 def _get_router(self, tenant_id):
123 """Retrieve a router for the given tenant id.
124
125 If a public router has been configured, it will be returned.
126
127 If a public router has not been configured, but a public
128 network has, a tenant router will be created and returned that
129 routes traffic to the public network.
130
131 """
132 router_id = self.config.network.public_router_id
133 network_id = self.config.network.public_network_id
134 if router_id:
135 result = self.network_client.show_router(router_id)
Maru Newby207d68c2013-04-09 01:06:03 +0000136 return net_common.AttributeDict(**result['router'])
Maru Newby81f07a02012-09-05 20:21:19 -0700137 elif network_id:
138 router = self._create_router(tenant_id)
139 router.add_gateway(network_id)
140 return router
141 else:
142 raise Exception("Neither of 'public_router_id' or "
143 "'public_network_id' has been defined.")
144
Gavin Brebner0f465a32013-03-14 13:26:09 +0000145 def _create_router(self, tenant_id, namestart='router-smoke-'):
146 name = rand_name(namestart)
Maru Newby81f07a02012-09-05 20:21:19 -0700147 body = dict(
148 router=dict(
149 name=name,
150 admin_state_up=True,
151 tenant_id=tenant_id,
152 ),
153 )
154 result = self.network_client.create_router(body=body)
Maru Newby207d68c2013-04-09 01:06:03 +0000155 router = net_common.DeletableRouter(client=self.network_client,
156 **result['router'])
Maru Newby81f07a02012-09-05 20:21:19 -0700157 self.assertEqual(router.name, name)
158 self.set_resource(name, router)
159 return router
160
Maru Newbybd360222013-04-08 22:48:50 +0000161 @attr(type='smoke')
Maru Newby81f07a02012-09-05 20:21:19 -0700162 def test_001_create_keypairs(self):
163 self.keypairs[self.tenant_id] = self._create_keypair(
164 self.compute_client)
165
Maru Newbybd360222013-04-08 22:48:50 +0000166 @attr(type='smoke')
Maru Newby81f07a02012-09-05 20:21:19 -0700167 def test_002_create_security_groups(self):
168 self.security_groups[self.tenant_id] = self._create_security_group(
169 self.compute_client)
170
Maru Newbybd360222013-04-08 22:48:50 +0000171 @attr(type='smoke')
Maru Newby81f07a02012-09-05 20:21:19 -0700172 def test_003_create_networks(self):
173 network = self._create_network(self.tenant_id)
174 router = self._get_router(self.tenant_id)
175 subnet = self._create_subnet(network)
176 subnet.add_to_router(router.id)
177 self.networks.append(network)
Gavin Brebner851c3502013-01-18 13:14:10 +0000178 self.subnets.append(subnet)
179 self.routers.append(router)
Maru Newby81f07a02012-09-05 20:21:19 -0700180
Maru Newbybd360222013-04-08 22:48:50 +0000181 @attr(type='smoke')
Gavin Brebner851c3502013-01-18 13:14:10 +0000182 def test_004_check_networks(self):
183 #Checks that we see the newly created network/subnet/router via
184 #checking the result of list_[networks,routers,subnets]
185 seen_nets = self._list_networks()
186 seen_names = [n['name'] for n in seen_nets]
187 seen_ids = [n['id'] for n in seen_nets]
188 for mynet in self.networks:
Gavin Brebner0f465a32013-03-14 13:26:09 +0000189 self.assertIn(mynet.name, seen_names)
190 self.assertIn(mynet.id, seen_ids)
Gavin Brebner851c3502013-01-18 13:14:10 +0000191 seen_subnets = self._list_subnets()
192 seen_net_ids = [n['network_id'] for n in seen_subnets]
193 seen_subnet_ids = [n['id'] for n in seen_subnets]
194 for mynet in self.networks:
Gavin Brebner0f465a32013-03-14 13:26:09 +0000195 self.assertIn(mynet.id, seen_net_ids)
Gavin Brebner851c3502013-01-18 13:14:10 +0000196 for mysubnet in self.subnets:
Gavin Brebner0f465a32013-03-14 13:26:09 +0000197 self.assertIn(mysubnet.id, seen_subnet_ids)
Gavin Brebner851c3502013-01-18 13:14:10 +0000198 seen_routers = self._list_routers()
199 seen_router_ids = [n['id'] for n in seen_routers]
200 seen_router_names = [n['name'] for n in seen_routers]
201 for myrouter in self.routers:
Gavin Brebner0f465a32013-03-14 13:26:09 +0000202 self.assertIn(myrouter.name, seen_router_names)
203 self.assertIn(myrouter.id, seen_router_ids)
Gavin Brebner851c3502013-01-18 13:14:10 +0000204
Maru Newbybd360222013-04-08 22:48:50 +0000205 @attr(type='smoke')
Gavin Brebner851c3502013-01-18 13:14:10 +0000206 def test_005_create_servers(self):
Maru Newby81f07a02012-09-05 20:21:19 -0700207 if not (self.keypairs or self.security_groups or self.networks):
ivan-zhu1feeb382013-01-24 10:14:39 +0800208 raise self.skipTest('Necessary resources have not been defined')
Maru Newby81f07a02012-09-05 20:21:19 -0700209 for i, network in enumerate(self.networks):
210 tenant_id = network.tenant_id
211 name = rand_name('server-smoke-%d-' % i)
212 keypair_name = self.keypairs[tenant_id].name
213 security_groups = [self.security_groups[tenant_id].name]
214 server = self._create_server(self.compute_client, network,
215 name, keypair_name, security_groups)
216 self.servers.append(server)
217
Maru Newbybd360222013-04-08 22:48:50 +0000218 @attr(type='smoke')
Gavin Brebner851c3502013-01-18 13:14:10 +0000219 def test_006_check_tenant_network_connectivity(self):
Maru Newby81f07a02012-09-05 20:21:19 -0700220 if not self.config.network.tenant_networks_reachable:
221 msg = 'Tenant networks not configured to be reachable.'
ivan-zhu1feeb382013-01-24 10:14:39 +0800222 raise self.skipTest(msg)
Maru Newby81f07a02012-09-05 20:21:19 -0700223 if not self.servers:
ivan-zhu1feeb382013-01-24 10:14:39 +0800224 raise self.skipTest("No VM's have been created")
Maru Newbyaf292e82013-05-20 21:32:28 +0000225 # The target login is assumed to have been configured for
226 # key-based authentication by cloud-init.
227 ssh_login = self.config.compute.image_ssh_user
228 private_key = self.keypairs[self.tenant_id].private_key
Maru Newby81f07a02012-09-05 20:21:19 -0700229 for server in self.servers:
230 for net_name, ip_addresses in server.networks.iteritems():
231 for ip_address in ip_addresses:
Maru Newbyaf292e82013-05-20 21:32:28 +0000232 self._check_vm_connectivity(ip_address, ssh_login,
233 private_key)
Maru Newby81f07a02012-09-05 20:21:19 -0700234
Maru Newbybd360222013-04-08 22:48:50 +0000235 @attr(type='smoke')
Gavin Brebner851c3502013-01-18 13:14:10 +0000236 def test_007_assign_floating_ips(self):
Maru Newby81f07a02012-09-05 20:21:19 -0700237 public_network_id = self.config.network.public_network_id
238 if not public_network_id:
ivan-zhu1feeb382013-01-24 10:14:39 +0800239 raise self.skipTest('Public network not configured')
Maru Newby81f07a02012-09-05 20:21:19 -0700240 if not self.servers:
ivan-zhu1feeb382013-01-24 10:14:39 +0800241 raise self.skipTest("No VM's have been created")
Maru Newby81f07a02012-09-05 20:21:19 -0700242 for server in self.servers:
243 floating_ip = self._create_floating_ip(server, public_network_id)
244 self.floating_ips.setdefault(server, [])
245 self.floating_ips[server].append(floating_ip)
246
Maru Newbybd360222013-04-08 22:48:50 +0000247 @attr(type='smoke')
Gavin Brebner851c3502013-01-18 13:14:10 +0000248 def test_008_check_public_network_connectivity(self):
Maru Newby81f07a02012-09-05 20:21:19 -0700249 if not self.floating_ips:
ivan-zhu1feeb382013-01-24 10:14:39 +0800250 raise self.skipTest('No floating ips have been allocated.')
Maru Newbyaf292e82013-05-20 21:32:28 +0000251 # The target login is assumed to have been configured for
252 # key-based authentication by cloud-init.
253 ssh_login = self.config.compute.image_ssh_user
254 private_key = self.keypairs[self.tenant_id].private_key
Maru Newby81f07a02012-09-05 20:21:19 -0700255 for server, floating_ips in self.floating_ips.iteritems():
256 for floating_ip in floating_ips:
257 ip_address = floating_ip.floating_ip_address
Maru Newbyaf292e82013-05-20 21:32:28 +0000258 self._check_vm_connectivity(ip_address, ssh_login, private_key)