blob: c9d2c7b085de725963ab49a8ceb345f899b203b4 [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
Solio Sarabia60095ff2017-02-28 18:18:26 -060085
Roman Popelka082919c2022-03-17 11:44:31 +010086class NetworkScenarioTest(manager.NetworkScenarioTest):
Solio Sarabia60095ff2017-02-28 18:18:26 -060087 """Base class for network scenario tests.
88
89 This class provide helpers for network scenario tests, using the neutron
90 API. Helpers from ancestor which use the nova network API are overridden
91 with the neutron API.
92
93 This Class also enforces using Neutron instead of novanetwork.
94 Subclassed tests will be skipped if Neutron is not enabled
95
96 """
97
Julia Kreger3a07c4d2021-06-22 10:27:56 -070098 credentials = ['primary', 'admin', 'system_admin']
Solio Sarabia60095ff2017-02-28 18:18:26 -060099
100 @classmethod
101 def skip_checks(cls):
102 super(NetworkScenarioTest, cls).skip_checks()
103 if not CONF.service_available.neutron:
104 raise cls.skipException('Neutron not available')
105
106 def _create_network(self, networks_client=None,
107 tenant_id=None,
108 namestart='network-smoke-',
109 port_security_enabled=True):
110 if not networks_client:
Julia Kreger3a07c4d2021-06-22 10:27:56 -0700111 networks_client = self.os_primary.networks_client
Solio Sarabia60095ff2017-02-28 18:18:26 -0600112 if not tenant_id:
Julia Kreger3a07c4d2021-06-22 10:27:56 -0700113 tenant_id = self.os_primary.networks_client.tenant_id
Solio Sarabia60095ff2017-02-28 18:18:26 -0600114 name = data_utils.rand_name(namestart)
115 network_kwargs = dict(name=name, tenant_id=tenant_id)
116 # Neutron disables port security by default so we have to check the
117 # config before trying to create the network with port_security_enabled
118 if CONF.network_feature_enabled.port_security:
119 network_kwargs['port_security_enabled'] = port_security_enabled
120 result = networks_client.create_network(**network_kwargs)
121 network = result['network']
122
123 self.assertEqual(network['name'], name)
124 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
125 networks_client.delete_network,
126 network['id'])
127 return network
128
Solio Sarabia60095ff2017-02-28 18:18:26 -0600129 def _get_server_port_id_and_ip4(self, server, ip_addr=None):
Hongbin Lu43015f02018-07-19 15:17:19 +0000130 if ip_addr:
131 ports = self.os_admin.ports_client.list_ports(
132 device_id=server['id'],
133 fixed_ips='ip_address=%s' % ip_addr)['ports']
134 else:
135 ports = self.os_admin.ports_client.list_ports(
136 device_id=server['id'])['ports']
Solio Sarabia60095ff2017-02-28 18:18:26 -0600137 # A port can have more than one IP address in some cases.
138 # If the network is dual-stack (IPv4 + IPv6), this port is associated
139 # with 2 subnets
140 p_status = ['ACTIVE']
141 # NOTE(vsaienko) With Ironic, instances live on separate hardware
142 # servers. Neutron does not bind ports for Ironic instances, as a
143 # result the port remains in the DOWN state.
144 # TODO(vsaienko) remove once bug: #1599836 is resolved.
145 if getattr(CONF.service_available, 'ironic', False):
146 p_status.append('DOWN')
147 port_map = [(p["id"], fxip["ip_address"])
148 for p in ports
149 for fxip in p["fixed_ips"]
150 if netutils.is_valid_ipv4(fxip["ip_address"])
151 and p['status'] in p_status]
152 inactive = [p for p in ports if p['status'] != 'ACTIVE']
153 if inactive:
154 LOG.warning("Instance has ports that are not ACTIVE: %s", inactive)
155
156 self.assertNotEqual(0, len(port_map),
157 "No IPv4 addresses found in: %s" % ports)
158 self.assertEqual(len(port_map), 1,
159 "Found multiple IPv4 addresses: %s. "
160 "Unable to determine which port to target."
161 % port_map)
162 return port_map[0]