blob: fe2833a26eaf6d8a829f568f9bc68106da469b46 [file] [log] [blame]
Andrea Frittolif4510a12017-03-07 19:17:11 +00001# 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
Andrea Frittolif4510a12017-03-07 19:17:11 +000017from oslo_log import log
Goutham Pacha Ravi37ee6772019-10-18 12:53:22 -070018from oslo_utils import uuidutils
Andrea Frittolif4510a12017-03-07 19:17:11 +000019from tempest import config
Ken'ichi Ohmichi02d1f242017-03-12 18:56:27 -070020from tempest.lib.common.utils import data_utils
Andrea Frittolif4510a12017-03-07 19:17:11 +000021from tempest.lib.common.utils import test_utils
22from tempest.lib import exceptions as lib_exc
Roman Popelka290ef292022-02-28 10:41:04 +010023from tempest.scenario import manager
Andrea Frittolif4510a12017-03-07 19:17:11 +000024
25CONF = config.CONF
26
27LOG = log.getLogger(__name__)
28
29
Roman Popelka1118f3e2022-03-21 09:18:53 +010030class ScenarioTest(manager.NetworkScenarioTest):
Andrea Frittolif4510a12017-03-07 19:17:11 +000031 """Base class for scenario tests. Uses tempest own clients. """
32
Andrea Frittolif4510a12017-03-07 19:17:11 +000033 # ## Test functions library
34 #
35 # The create_[resource] functions only return body and discard the
36 # resp part which is not used in scenario tests
37
Andrea Frittolif4510a12017-03-07 19:17:11 +000038 def _image_create(self, name, fmt, path,
39 disk_format=None, properties=None):
40 if properties is None:
41 properties = {}
42 name = data_utils.rand_name('%s-' % name)
43 params = {
44 'name': name,
45 'container_format': fmt,
46 'disk_format': disk_format or fmt,
Ghanshyam Mann9cf773d2023-08-06 11:52:39 -070047 'visibility': 'private'
Andrea Frittolif4510a12017-03-07 19:17:11 +000048 }
Ghanshyam Mann9cf773d2023-08-06 11:52:39 -070049 # Additional properties are flattened out in the v2 API.
50 params.update(properties)
Andrea Frittolif4510a12017-03-07 19:17:11 +000051 body = self.image_client.create_image(**params)
52 image = body['image'] if 'image' in body else body
53 self.addCleanup(self.image_client.delete_image, image['id'])
54 self.assertEqual("queued", image['status'])
55 with open(path, 'rb') as image_file:
Ghanshyam Mann9cf773d2023-08-06 11:52:39 -070056 self.image_client.store_image_file(image['id'], image_file)
Andrea Frittolif4510a12017-03-07 19:17:11 +000057 return image['id']
58
59 def glance_image_create(self):
Martin Kopec258cc6c2020-04-15 22:55:25 +000060 img_path = CONF.scenario.img_file
Andrea Frittolif4510a12017-03-07 19:17:11 +000061 img_container_format = CONF.scenario.img_container_format
62 img_disk_format = CONF.scenario.img_disk_format
63 img_properties = CONF.scenario.img_properties
64 LOG.debug("paths: img: %s, container_format: %s, disk_format: %s, "
Martin Kopec258cc6c2020-04-15 22:55:25 +000065 "properties: %s",
Andrea Frittolif4510a12017-03-07 19:17:11 +000066 img_path, img_container_format, img_disk_format,
Martin Kopec258cc6c2020-04-15 22:55:25 +000067 img_properties)
68 image = self._image_create('scenario-img',
69 img_container_format,
70 img_path,
71 disk_format=img_disk_format,
72 properties=img_properties)
Andrea Frittolif4510a12017-03-07 19:17:11 +000073 LOG.debug("image:%s", image)
74
75 return image
76
Andrea Frittolif4510a12017-03-07 19:17:11 +000077 def _log_net_info(self, exc):
78 # network debug is called as part of ssh init
79 if not isinstance(exc, lib_exc.SSHTimeout):
80 LOG.debug('Network information on a devstack host')
81
Andrea Frittolif4510a12017-03-07 19:17:11 +000082
83class NetworkScenarioTest(ScenarioTest):
84 """Base class for network scenario tests.
85
86 This class provide helpers for network scenario tests, using the neutron
87 API. Helpers from ancestor which use the nova network API are overridden
88 with the neutron API.
89
90 This Class also enforces using Neutron instead of novanetwork.
91 Subclassed tests will be skipped if Neutron is not enabled
92
93 """
94
Andrea Frittolif4510a12017-03-07 19:17:11 +000095 @classmethod
96 def skip_checks(cls):
97 super(NetworkScenarioTest, cls).skip_checks()
98 if not CONF.service_available.neutron:
99 raise cls.skipException('Neutron not available')
100
Goutham Pacha Ravi37ee6772019-10-18 12:53:22 -0700101 def _get_network_by_name_or_id(self, identifier):
102
103 if uuidutils.is_uuid_like(identifier):
104 return self.os_admin.networks_client.show_network(
105 identifier)['network']
106
107 networks = self.os_admin.networks_client.list_networks(
108 name=identifier)['networks']
109 self.assertNotEqual(len(networks), 0,
110 "Unable to get network by name: %s" % identifier)
111 return networks[0]
112
Andrea Frittolif4510a12017-03-07 19:17:11 +0000113 def create_floating_ip(self, thing, external_network_id=None,
lkuchlan7636a1f2020-04-30 16:13:13 +0300114 port_id=None, ip_addr=None, client=None):
Andrea Frittolif4510a12017-03-07 19:17:11 +0000115 """Create a floating IP and associates to a resource/port on Neutron"""
116 if not external_network_id:
117 external_network_id = CONF.network.public_network_id
118 if not client:
119 client = self.floating_ips_client
120 if not port_id:
Roman Popelkaf880ce32022-03-22 13:26:51 +0100121 port_id, ip4 = self.get_server_port_id_and_ip4(thing,
122 ip_addr=ip_addr)
Andrea Frittolif4510a12017-03-07 19:17:11 +0000123 else:
124 ip4 = None
125 result = client.create_floatingip(
126 floating_network_id=external_network_id,
127 port_id=port_id,
128 tenant_id=thing['tenant_id'],
129 fixed_ip_address=ip4
130 )
131 floating_ip = result['floatingip']
132 self.addCleanup(test_utils.call_and_ignore_notfound_exc,
133 client.delete_floatingip,
134 floating_ip['id'])
135 return floating_ip
136
Roman Popelka22fde6a2022-03-24 10:45:05 +0100137 def create_loginable_secgroup_rule(self, security_group_rules_client=None,
138 secgroup=None,
139 security_groups_client=None):
Andrea Frittolif4510a12017-03-07 19:17:11 +0000140 """Create loginable security group rule
141
142 This function will create:
143 1. egress and ingress tcp port 22 allow rule in order to allow ssh
144 access for ipv4.
145 2. egress and ingress ipv6 icmp allow rule, in order to allow icmpv6.
146 3. egress and ingress ipv4 icmp allow rule, in order to allow icmpv4.
147 """
148
149 if security_group_rules_client is None:
150 security_group_rules_client = self.security_group_rules_client
151 if security_groups_client is None:
152 security_groups_client = self.security_groups_client
153 rules = []
154 rulesets = [
155 dict(
156 # ssh
157 protocol='tcp',
158 port_range_min=22,
159 port_range_max=22,
160 ),
161 dict(
Rodrigo Barbieri797257e2017-11-21 11:00:45 -0200162 # ipv6-ssh
163 protocol='tcp',
164 port_range_min=22,
165 port_range_max=22,
166 ethertype='IPv6',
167 ),
168 dict(
Andrea Frittolif4510a12017-03-07 19:17:11 +0000169 # ping
170 protocol='icmp',
171 ),
172 dict(
173 # ipv6-icmp for ping6
174 protocol='icmp',
175 ethertype='IPv6',
176 )
177 ]
178 sec_group_rules_client = security_group_rules_client
179 for ruleset in rulesets:
180 for r_direction in ['ingress', 'egress']:
181 ruleset['direction'] = r_direction
182 try:
Roman Popelka0cf32fb2022-03-24 11:14:49 +0100183 sg_rule = self.create_security_group_rule(
Andrea Frittolif4510a12017-03-07 19:17:11 +0000184 sec_group_rules_client=sec_group_rules_client,
185 secgroup=secgroup,
186 security_groups_client=security_groups_client,
187 **ruleset)
188 except lib_exc.Conflict as ex:
189 # if rule already exist - skip rule and continue
190 msg = 'Security group rule already exists'
191 if msg not in ex._error_string:
192 raise ex
193 else:
194 self.assertEqual(r_direction, sg_rule['direction'])
195 rules.append(sg_rule)
196
197 return rules