blob: 390e0047cf05b215a12aefb950cb05c9b1508643 [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
Sean Dague6dbc6da2013-05-08 17:49:46 -040021from tempest.scenario import manager
Maru Newbybd360222013-04-08 22:48:50 +000022from tempest.test import attr
Maru Newby81f07a02012-09-05 20:21:19 -070023
24
Sean Dague6dbc6da2013-05-08 17:49:46 -040025class TestNetworkBasicOps(manager.NetworkScenarioTest):
Maru Newby81f07a02012-09-05 20:21:19 -070026
27 """
28 This smoke test suite assumes that Nova has been configured to
Mark McClainf2982e82013-07-06 17:48:03 -040029 boot VM's with Neutron-managed networking, and attempts to
Maru Newby81f07a02012-09-05 20:21:19 -070030 verify network connectivity as follows:
31
32 * For a freshly-booted VM with an IP address ("port") on a given network:
33
Maru Newbyaf292e82013-05-20 21:32:28 +000034 - the Tempest host can ping the IP address. This implies, but
35 does not guarantee (see the ssh check that follows), that the
36 VM has been assigned the correct IP address and has
Maru Newby81f07a02012-09-05 20:21:19 -070037 connectivity to the Tempest host.
38
Maru Newbyaf292e82013-05-20 21:32:28 +000039 - the Tempest host can perform key-based authentication to an
40 ssh server hosted at the IP address. This check guarantees
41 that the IP address is associated with the target VM.
42
Maru Newby81f07a02012-09-05 20:21:19 -070043 #TODO(mnewby) - Need to implement the following:
44 - the Tempest host can ssh into the VM via the IP address and
45 successfully execute the following:
46
47 - ping an external IP address, implying external connectivity.
48
49 - ping an external hostname, implying that dns is correctly
50 configured.
51
52 - ping an internal IP address, implying connectivity to another
53 VM on the same network.
54
55 There are presumed to be two types of networks: tenant and
56 public. A tenant network may or may not be reachable from the
57 Tempest host. A public network is assumed to be reachable from
58 the Tempest host, and it should be possible to associate a public
59 ('floating') IP address with a tenant ('fixed') IP address to
60 faciliate external connectivity to a potentially unroutable
61 tenant IP address.
62
63 This test suite can be configured to test network connectivity to
64 a VM via a tenant network, a public network, or both. If both
65 networking types are to be evaluated, tests that need to be
66 executed remotely on the VM (via ssh) will only be run against
67 one of the networks (to minimize test execution time).
68
69 Determine which types of networks to test as follows:
70
71 * Configure tenant network checks (via the
72 'tenant_networks_reachable' key) if the Tempest host should
73 have direct connectivity to tenant networks. This is likely to
74 be the case if Tempest is running on the same host as a
75 single-node devstack installation with IP namespaces disabled.
76
77 * Configure checks for a public network if a public network has
78 been configured prior to the test suite being run and if the
79 Tempest host should have connectivity to that public network.
80 Checking connectivity for a public network requires that a
81 value be provided for 'public_network_id'. A value can
82 optionally be provided for 'public_router_id' if tenants will
83 use a shared router to access a public network (as is likely to
84 be the case when IP namespaces are not enabled). If a value is
85 not provided for 'public_router_id', a router will be created
86 for each tenant and use the network identified by
87 'public_network_id' as its gateway.
88
89 """
90
91 @classmethod
92 def check_preconditions(cls):
Gavin Brebner0f465a32013-03-14 13:26:09 +000093 super(TestNetworkBasicOps, cls).check_preconditions()
Maru Newby81f07a02012-09-05 20:21:19 -070094 cfg = cls.config.network
Maru Newby81f07a02012-09-05 20:21:19 -070095 if not (cfg.tenant_networks_reachable or cfg.public_network_id):
96 msg = ('Either tenant_networks_reachable must be "true", or '
97 'public_network_id must be defined.')
Gavin Brebner0f465a32013-03-14 13:26:09 +000098 cls.enabled = False
ivan-zhu1feeb382013-01-24 10:14:39 +080099 raise cls.skipException(msg)
Maru Newby81f07a02012-09-05 20:21:19 -0700100
101 @classmethod
102 def setUpClass(cls):
103 super(TestNetworkBasicOps, cls).setUpClass()
104 cls.check_preconditions()
Maru Newby81f07a02012-09-05 20:21:19 -0700105 cls.tenant_id = cls.manager._get_identity_client(
Gavin Brebnercb7faa32013-01-30 12:01:31 +0000106 cls.config.identity.username,
107 cls.config.identity.password,
108 cls.config.identity.tenant_name).tenant_id
Maru Newby81f07a02012-09-05 20:21:19 -0700109 # TODO(mnewby) Consider looking up entities as needed instead
110 # of storing them as collections on the class.
111 cls.keypairs = {}
112 cls.security_groups = {}
113 cls.networks = []
Gavin Brebner851c3502013-01-18 13:14:10 +0000114 cls.subnets = []
115 cls.routers = []
Maru Newby81f07a02012-09-05 20:21:19 -0700116 cls.servers = []
117 cls.floating_ips = {}
118
Maru Newby81f07a02012-09-05 20:21:19 -0700119 def _get_router(self, tenant_id):
120 """Retrieve a router for the given tenant id.
121
122 If a public router has been configured, it will be returned.
123
124 If a public router has not been configured, but a public
125 network has, a tenant router will be created and returned that
126 routes traffic to the public network.
127
128 """
129 router_id = self.config.network.public_router_id
130 network_id = self.config.network.public_network_id
131 if router_id:
132 result = self.network_client.show_router(router_id)
Maru Newby207d68c2013-04-09 01:06:03 +0000133 return net_common.AttributeDict(**result['router'])
Maru Newby81f07a02012-09-05 20:21:19 -0700134 elif network_id:
135 router = self._create_router(tenant_id)
136 router.add_gateway(network_id)
137 return router
138 else:
139 raise Exception("Neither of 'public_router_id' or "
140 "'public_network_id' has been defined.")
141
Gavin Brebner0f465a32013-03-14 13:26:09 +0000142 def _create_router(self, tenant_id, namestart='router-smoke-'):
143 name = rand_name(namestart)
Maru Newby81f07a02012-09-05 20:21:19 -0700144 body = dict(
145 router=dict(
146 name=name,
147 admin_state_up=True,
148 tenant_id=tenant_id,
149 ),
150 )
151 result = self.network_client.create_router(body=body)
Maru Newby207d68c2013-04-09 01:06:03 +0000152 router = net_common.DeletableRouter(client=self.network_client,
153 **result['router'])
Maru Newby81f07a02012-09-05 20:21:19 -0700154 self.assertEqual(router.name, name)
155 self.set_resource(name, router)
156 return router
157
Maru Newbybd360222013-04-08 22:48:50 +0000158 @attr(type='smoke')
Maru Newby81f07a02012-09-05 20:21:19 -0700159 def test_001_create_keypairs(self):
160 self.keypairs[self.tenant_id] = self._create_keypair(
161 self.compute_client)
162
Maru Newbybd360222013-04-08 22:48:50 +0000163 @attr(type='smoke')
Maru Newby81f07a02012-09-05 20:21:19 -0700164 def test_002_create_security_groups(self):
165 self.security_groups[self.tenant_id] = self._create_security_group(
166 self.compute_client)
167
Maru Newbybd360222013-04-08 22:48:50 +0000168 @attr(type='smoke')
Maru Newby81f07a02012-09-05 20:21:19 -0700169 def test_003_create_networks(self):
170 network = self._create_network(self.tenant_id)
171 router = self._get_router(self.tenant_id)
172 subnet = self._create_subnet(network)
173 subnet.add_to_router(router.id)
174 self.networks.append(network)
Gavin Brebner851c3502013-01-18 13:14:10 +0000175 self.subnets.append(subnet)
176 self.routers.append(router)
Maru Newby81f07a02012-09-05 20:21:19 -0700177
Maru Newbybd360222013-04-08 22:48:50 +0000178 @attr(type='smoke')
Gavin Brebner851c3502013-01-18 13:14:10 +0000179 def test_004_check_networks(self):
180 #Checks that we see the newly created network/subnet/router via
181 #checking the result of list_[networks,routers,subnets]
182 seen_nets = self._list_networks()
183 seen_names = [n['name'] for n in seen_nets]
184 seen_ids = [n['id'] for n in seen_nets]
185 for mynet in self.networks:
Gavin Brebner0f465a32013-03-14 13:26:09 +0000186 self.assertIn(mynet.name, seen_names)
187 self.assertIn(mynet.id, seen_ids)
Gavin Brebner851c3502013-01-18 13:14:10 +0000188 seen_subnets = self._list_subnets()
189 seen_net_ids = [n['network_id'] for n in seen_subnets]
190 seen_subnet_ids = [n['id'] for n in seen_subnets]
191 for mynet in self.networks:
Gavin Brebner0f465a32013-03-14 13:26:09 +0000192 self.assertIn(mynet.id, seen_net_ids)
Gavin Brebner851c3502013-01-18 13:14:10 +0000193 for mysubnet in self.subnets:
Gavin Brebner0f465a32013-03-14 13:26:09 +0000194 self.assertIn(mysubnet.id, seen_subnet_ids)
Gavin Brebner851c3502013-01-18 13:14:10 +0000195 seen_routers = self._list_routers()
196 seen_router_ids = [n['id'] for n in seen_routers]
197 seen_router_names = [n['name'] for n in seen_routers]
198 for myrouter in self.routers:
Gavin Brebner0f465a32013-03-14 13:26:09 +0000199 self.assertIn(myrouter.name, seen_router_names)
200 self.assertIn(myrouter.id, seen_router_ids)
Gavin Brebner851c3502013-01-18 13:14:10 +0000201
Maru Newbybd360222013-04-08 22:48:50 +0000202 @attr(type='smoke')
Gavin Brebner851c3502013-01-18 13:14:10 +0000203 def test_005_create_servers(self):
Maru Newby81f07a02012-09-05 20:21:19 -0700204 if not (self.keypairs or self.security_groups or self.networks):
ivan-zhu1feeb382013-01-24 10:14:39 +0800205 raise self.skipTest('Necessary resources have not been defined')
Maru Newby81f07a02012-09-05 20:21:19 -0700206 for i, network in enumerate(self.networks):
207 tenant_id = network.tenant_id
208 name = rand_name('server-smoke-%d-' % i)
209 keypair_name = self.keypairs[tenant_id].name
210 security_groups = [self.security_groups[tenant_id].name]
211 server = self._create_server(self.compute_client, network,
212 name, keypair_name, security_groups)
213 self.servers.append(server)
214
Maru Newbybd360222013-04-08 22:48:50 +0000215 @attr(type='smoke')
Gavin Brebner851c3502013-01-18 13:14:10 +0000216 def test_006_check_tenant_network_connectivity(self):
Maru Newby81f07a02012-09-05 20:21:19 -0700217 if not self.config.network.tenant_networks_reachable:
218 msg = 'Tenant networks not configured to be reachable.'
ivan-zhu1feeb382013-01-24 10:14:39 +0800219 raise self.skipTest(msg)
Maru Newby81f07a02012-09-05 20:21:19 -0700220 if not self.servers:
ivan-zhu1feeb382013-01-24 10:14:39 +0800221 raise self.skipTest("No VM's have been created")
Maru Newbyaf292e82013-05-20 21:32:28 +0000222 # The target login is assumed to have been configured for
223 # key-based authentication by cloud-init.
224 ssh_login = self.config.compute.image_ssh_user
225 private_key = self.keypairs[self.tenant_id].private_key
Maru Newby81f07a02012-09-05 20:21:19 -0700226 for server in self.servers:
227 for net_name, ip_addresses in server.networks.iteritems():
228 for ip_address in ip_addresses:
Maru Newbyaf292e82013-05-20 21:32:28 +0000229 self._check_vm_connectivity(ip_address, ssh_login,
230 private_key)
Maru Newby81f07a02012-09-05 20:21:19 -0700231
Maru Newbybd360222013-04-08 22:48:50 +0000232 @attr(type='smoke')
Gavin Brebner851c3502013-01-18 13:14:10 +0000233 def test_007_assign_floating_ips(self):
Maru Newby81f07a02012-09-05 20:21:19 -0700234 public_network_id = self.config.network.public_network_id
235 if not public_network_id:
ivan-zhu1feeb382013-01-24 10:14:39 +0800236 raise self.skipTest('Public network not configured')
Maru Newby81f07a02012-09-05 20:21:19 -0700237 if not self.servers:
ivan-zhu1feeb382013-01-24 10:14:39 +0800238 raise self.skipTest("No VM's have been created")
Maru Newby81f07a02012-09-05 20:21:19 -0700239 for server in self.servers:
240 floating_ip = self._create_floating_ip(server, public_network_id)
241 self.floating_ips.setdefault(server, [])
242 self.floating_ips[server].append(floating_ip)
243
Maru Newbybd360222013-04-08 22:48:50 +0000244 @attr(type='smoke')
Gavin Brebner851c3502013-01-18 13:14:10 +0000245 def test_008_check_public_network_connectivity(self):
Maru Newby81f07a02012-09-05 20:21:19 -0700246 if not self.floating_ips:
ivan-zhu1feeb382013-01-24 10:14:39 +0800247 raise self.skipTest('No floating ips have been allocated.')
Maru Newbyaf292e82013-05-20 21:32:28 +0000248 # The target login is assumed to have been configured for
249 # key-based authentication by cloud-init.
250 ssh_login = self.config.compute.image_ssh_user
251 private_key = self.keypairs[self.tenant_id].private_key
Maru Newby81f07a02012-09-05 20:21:19 -0700252 for server, floating_ips in self.floating_ips.iteritems():
253 for floating_ip in floating_ips:
254 ip_address = floating_ip.floating_ip_address
Maru Newbyaf292e82013-05-20 21:32:28 +0000255 self._check_vm_connectivity(ip_address, ssh_login, private_key)