blob: 4c2f45bdae980a49d21deb23f05a1d0f9da1236b [file] [log] [blame]
Solio Sarabia60095ff2017-02-28 18:18:26 -06001# Copyright 2012 OpenStack Foundation
2# Copyright 2013 IBM Corp.
3# 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.
16
17# NOTE(soliosg) Do not edit this file. It will only stay temporarily
18# in ironic, while QA refactors the tempest.scenario interface. This
19# file was copied from openstack/tempest/tempest/scenario/manager.py,
20# openstack/tempest commit: 82a278e88c9e9f9ba49f81c1f8dba0bca7943daf
21
Solio Sarabia60095ff2017-02-28 18:18:26 -060022from oslo_log import log
Solio Sarabia60095ff2017-02-28 18:18:26 -060023from oslo_utils import netutils
Solio Sarabia60095ff2017-02-28 18:18:26 -060024from tempest import config
Solio Sarabia60095ff2017-02-28 18:18:26 -060025from tempest.lib.common.utils import data_utils
26from tempest.lib.common.utils import test_utils
27from tempest.lib import exceptions as lib_exc
Roman Popelka082919c2022-03-17 11:44:31 +010028from tempest.scenario import manager
Solio Sarabia60095ff2017-02-28 18:18:26 -060029
30CONF = config.CONF
31
32LOG = log.getLogger(__name__)
33
34
Roman Popelka082919c2022-03-17 11:44:31 +010035class ScenarioTest(manager.ScenarioTest):
Solio Sarabia60095ff2017-02-28 18:18:26 -060036 """Base class for scenario tests. Uses tempest own clients. """
37
Julia Kreger3a07c4d2021-06-22 10:27:56 -070038 credentials = ['primary', 'admin', 'system_admin']
Solio Sarabia60095ff2017-02-28 18:18:26 -060039
40 @classmethod
41 def setup_clients(cls):
42 super(ScenarioTest, cls).setup_clients()
43 # Clients (in alphabetical order)
Vu Cong Tuanf825d192017-06-21 18:32:15 +070044 cls.flavors_client = cls.os_primary.flavors_client
Solio Sarabia60095ff2017-02-28 18:18:26 -060045 cls.compute_floating_ips_client = (
Vu Cong Tuanf825d192017-06-21 18:32:15 +070046 cls.os_primary.compute_floating_ips_client)
Solio Sarabia60095ff2017-02-28 18:18:26 -060047 if CONF.service_available.glance:
48 # Check if glance v1 is available to determine which client to use.
49 if CONF.image_feature_enabled.api_v1:
Vu Cong Tuanf825d192017-06-21 18:32:15 +070050 cls.image_client = cls.os_primary.image_client
Solio Sarabia60095ff2017-02-28 18:18:26 -060051 elif CONF.image_feature_enabled.api_v2:
Vu Cong Tuanf825d192017-06-21 18:32:15 +070052 cls.image_client = cls.os_primary.image_client_v2
Solio Sarabia60095ff2017-02-28 18:18:26 -060053 else:
54 raise lib_exc.InvalidConfiguration(
55 'Either api_v1 or api_v2 must be True in '
56 '[image-feature-enabled].')
57 # Compute image client
Vu Cong Tuanf825d192017-06-21 18:32:15 +070058 cls.compute_images_client = cls.os_primary.compute_images_client
59 cls.keypairs_client = cls.os_primary.keypairs_client
Solio Sarabia60095ff2017-02-28 18:18:26 -060060 # Nova security groups client
61 cls.compute_security_groups_client = (
Vu Cong Tuanf825d192017-06-21 18:32:15 +070062 cls.os_primary.compute_security_groups_client)
Solio Sarabia60095ff2017-02-28 18:18:26 -060063 cls.compute_security_group_rules_client = (
Vu Cong Tuanf825d192017-06-21 18:32:15 +070064 cls.os_primary.compute_security_group_rules_client)
65 cls.servers_client = cls.os_primary.servers_client
66 cls.interface_client = cls.os_primary.interfaces_client
Solio Sarabia60095ff2017-02-28 18:18:26 -060067 # Neutron network client
Vu Cong Tuanf825d192017-06-21 18:32:15 +070068 cls.networks_client = cls.os_primary.networks_client
69 cls.ports_client = cls.os_primary.ports_client
70 cls.routers_client = cls.os_primary.routers_client
71 cls.subnets_client = cls.os_primary.subnets_client
72 cls.floating_ips_client = cls.os_primary.floating_ips_client
73 cls.security_groups_client = cls.os_primary.security_groups_client
Solio Sarabia60095ff2017-02-28 18:18:26 -060074 cls.security_group_rules_client = (
Vu Cong Tuanf825d192017-06-21 18:32:15 +070075 cls.os_primary.security_group_rules_client)
Solio Sarabia60095ff2017-02-28 18:18:26 -060076
Ghanshyam Mann3b663f62019-12-12 17:01:16 +000077 cls.volumes_client = cls.os_primary.volumes_client_latest
78 cls.snapshots_client = cls.os_primary.snapshots_client_latest
Solio Sarabia60095ff2017-02-28 18:18:26 -060079
80 # ## Test functions library
81 #
82 # The create_[resource] functions only return body and discard the
83 # resp part which is not used in scenario tests
84
Pavlo Shchelokovskyy40db0332017-03-21 08:00:17 +000085 def _get_router(self, client=None, tenant_id=None):
86 """Retrieve a router for the given tenant id.
87
88 If a public router has been configured, it will be returned.
89
90 If a public router has not been configured, but a public
91 network has, a tenant router will be created and returned that
92 routes traffic to the public network.
93 """
94 if not client:
Julia Kreger3a07c4d2021-06-22 10:27:56 -070095 client = self.os_primary.routers_client
Pavlo Shchelokovskyy40db0332017-03-21 08:00:17 +000096 if not tenant_id:
97 tenant_id = client.tenant_id
98 router_id = CONF.network.public_router_id
99 network_id = CONF.network.public_network_id
100 if router_id:
101 body = client.show_router(router_id)
102 return body['router']
103 elif network_id:
104 router = self._create_router(client, tenant_id)
105 kwargs = {'external_gateway_info': dict(network_id=network_id)}
106 router = client.update_router(router['id'], **kwargs)['router']
107 return router
108 else:
109 raise Exception("Neither of 'public_router_id' or "
110 "'public_network_id' has been defined.")
111
112 def _create_router(self, client=None, tenant_id=None,
113 namestart='router-smoke'):
114 if not client:
Julia Kreger3a07c4d2021-06-22 10:27:56 -0700115 client = self.os_primary.routers_client
Pavlo Shchelokovskyy40db0332017-03-21 08:00:17 +0000116 if not tenant_id:
117 tenant_id = client.tenant_id
118 name = data_utils.rand_name(namestart)
119 result = client.create_router(name=name,
120 admin_state_up=True,
121 tenant_id=tenant_id)
122 router = result['router']
123 self.assertEqual(router['name'], name)
124 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
125 client.delete_router,
126 router['id'])
127 return router
128
Solio Sarabia60095ff2017-02-28 18:18:26 -0600129
Roman Popelka082919c2022-03-17 11:44:31 +0100130class NetworkScenarioTest(manager.NetworkScenarioTest):
Solio Sarabia60095ff2017-02-28 18:18:26 -0600131 """Base class for network scenario tests.
132
133 This class provide helpers for network scenario tests, using the neutron
134 API. Helpers from ancestor which use the nova network API are overridden
135 with the neutron API.
136
137 This Class also enforces using Neutron instead of novanetwork.
138 Subclassed tests will be skipped if Neutron is not enabled
139
140 """
141
Julia Kreger3a07c4d2021-06-22 10:27:56 -0700142 credentials = ['primary', 'admin', 'system_admin']
Solio Sarabia60095ff2017-02-28 18:18:26 -0600143
144 @classmethod
145 def skip_checks(cls):
146 super(NetworkScenarioTest, cls).skip_checks()
147 if not CONF.service_available.neutron:
148 raise cls.skipException('Neutron not available')
149
150 def _create_network(self, networks_client=None,
151 tenant_id=None,
152 namestart='network-smoke-',
153 port_security_enabled=True):
154 if not networks_client:
Julia Kreger3a07c4d2021-06-22 10:27:56 -0700155 networks_client = self.os_primary.networks_client
Solio Sarabia60095ff2017-02-28 18:18:26 -0600156 if not tenant_id:
Julia Kreger3a07c4d2021-06-22 10:27:56 -0700157 tenant_id = self.os_primary.networks_client.tenant_id
Solio Sarabia60095ff2017-02-28 18:18:26 -0600158 name = data_utils.rand_name(namestart)
159 network_kwargs = dict(name=name, tenant_id=tenant_id)
160 # Neutron disables port security by default so we have to check the
161 # config before trying to create the network with port_security_enabled
162 if CONF.network_feature_enabled.port_security:
163 network_kwargs['port_security_enabled'] = port_security_enabled
164 result = networks_client.create_network(**network_kwargs)
165 network = result['network']
166
167 self.assertEqual(network['name'], name)
168 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
169 networks_client.delete_network,
170 network['id'])
171 return network
172
Solio Sarabia60095ff2017-02-28 18:18:26 -0600173 def _get_server_port_id_and_ip4(self, server, ip_addr=None):
Hongbin Lu43015f02018-07-19 15:17:19 +0000174 if ip_addr:
175 ports = self.os_admin.ports_client.list_ports(
176 device_id=server['id'],
177 fixed_ips='ip_address=%s' % ip_addr)['ports']
178 else:
179 ports = self.os_admin.ports_client.list_ports(
180 device_id=server['id'])['ports']
Solio Sarabia60095ff2017-02-28 18:18:26 -0600181 # A port can have more than one IP address in some cases.
182 # If the network is dual-stack (IPv4 + IPv6), this port is associated
183 # with 2 subnets
184 p_status = ['ACTIVE']
185 # NOTE(vsaienko) With Ironic, instances live on separate hardware
186 # servers. Neutron does not bind ports for Ironic instances, as a
187 # result the port remains in the DOWN state.
188 # TODO(vsaienko) remove once bug: #1599836 is resolved.
189 if getattr(CONF.service_available, 'ironic', False):
190 p_status.append('DOWN')
191 port_map = [(p["id"], fxip["ip_address"])
192 for p in ports
193 for fxip in p["fixed_ips"]
194 if netutils.is_valid_ipv4(fxip["ip_address"])
195 and p['status'] in p_status]
196 inactive = [p for p in ports if p['status'] != 'ACTIVE']
197 if inactive:
198 LOG.warning("Instance has ports that are not ACTIVE: %s", inactive)
199
200 self.assertNotEqual(0, len(port_map),
201 "No IPv4 addresses found in: %s" % ports)
202 self.assertEqual(len(port_map), 1,
203 "Found multiple IPv4 addresses: %s. "
204 "Unable to determine which port to target."
205 % port_map)
206 return port_map[0]