blob: 4cd860d9f12e629953462f5a4393a5720d0fe4e3 [file] [log] [blame]
Masayuki Igawa73d9f3a2013-05-24 10:30:01 +09001# Copyright 2013 NEC Corporation
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
Andrea Frittoli247058f2014-07-16 16:09:22 +010016from tempest.common import custom_matchers
Andrea Frittolicd368412017-08-14 21:37:56 +010017from tempest.common import utils
Ken'ichi Ohmichi0eb153c2015-07-13 02:18:25 +000018from tempest.common import waiters
Matthew Treinish6c072292014-01-29 19:15:52 +000019from tempest import config
Jordan Pittier35a63752016-08-30 13:09:12 +020020from tempest.lib.common.utils import test_utils
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -080021from tempest.lib import decorators
guo yunxian7383a6f2016-12-05 18:56:51 +080022from tempest.lib import exceptions
Masayuki Igawa73d9f3a2013-05-24 10:30:01 +090023from tempest.scenario import manager
24
Matthew Treinish6c072292014-01-29 19:15:52 +000025CONF = config.CONF
Masayuki Igawa73d9f3a2013-05-24 10:30:01 +090026
Masayuki Igawa73d9f3a2013-05-24 10:30:01 +090027
Andrea Frittoli247058f2014-07-16 16:09:22 +010028class TestMinimumBasicScenario(manager.ScenarioTest):
Masayuki Igawa73d9f3a2013-05-24 10:30:01 +090029
Ken'ichi Ohmichic4e4f1c2015-11-17 08:16:12 +000030 """This is a basic minimum scenario test.
Masayuki Igawa73d9f3a2013-05-24 10:30:01 +090031
32 This test below:
33 * across the multiple components
34 * as a regular user
35 * with and without optional parameters
36 * check command outputs
37
Alexander Gubanova5ab12e2015-11-17 18:18:46 +020038 Steps:
39 1. Create image
40 2. Create keypair
41 3. Boot instance with keypair and get list of instances
42 4. Create volume and show list of volumes
43 5. Attach volume to instance and getlist of volumes
44 6. Add IP to instance
45 7. Create and add security group to instance
46 8. Check SSH connection to instance
47 9. Reboot instance
48 10. Check SSH connection to instance after reboot
49
Masayuki Igawa73d9f3a2013-05-24 10:30:01 +090050 """
afazekas40fcb9b2019-03-08 11:25:11 +010051
Jordan Pittier7cf64762015-10-14 15:01:12 +020052 def nova_show(self, server):
53 got_server = (self.servers_client.show_server(server['id'])
ghanshyam0f825252015-08-25 16:02:50 +090054 ['server'])
Jordan Pittier5d367152015-08-19 12:03:49 +020055 excluded_keys = ['OS-EXT-AZ:availability_zone']
56 # Exclude these keys because of LP:#1486475
57 excluded_keys.extend(['OS-EXT-STS:power_state', 'updated'])
Andrea Frittoli247058f2014-07-16 16:09:22 +010058 self.assertThat(
Jordan Pittier7cf64762015-10-14 15:01:12 +020059 server, custom_matchers.MatchesDictExceptForKeys(
Jordan Pittier5d367152015-08-19 12:03:49 +020060 got_server, excluded_keys=excluded_keys))
Masayuki Igawa73d9f3a2013-05-24 10:30:01 +090061
Jordan Pittier7cf64762015-10-14 15:01:12 +020062 def cinder_show(self, volume):
63 got_volume = self.volumes_client.show_volume(volume['id'])['volume']
Matt Riedemann3ec41c22019-10-15 11:39:32 -040064 # Exclude updated_at because of bug 1838202.
65 excluded_keys = ['updated_at']
66 self.assertThat(
67 volume, custom_matchers.MatchesDictExceptForKeys(
68 got_volume, excluded_keys=excluded_keys))
Masayuki Igawa73d9f3a2013-05-24 10:30:01 +090069
Jordan Pittier7cf64762015-10-14 15:01:12 +020070 def nova_reboot(self, server):
Ken'ichi Ohmichi36b714c2015-12-09 08:12:47 +000071 self.servers_client.reboot_server(server['id'], type='SOFT')
Masayuki Igawa8bf68672016-01-15 14:43:10 +090072 waiters.wait_for_server_status(self.servers_client,
73 server['id'], 'ACTIVE')
Masayuki Igawa73d9f3a2013-05-24 10:30:01 +090074
Evgeny Antyshev4894a912016-11-21 12:17:18 +000075 def check_disks(self):
Andrea Frittoli247058f2014-07-16 16:09:22 +010076 # NOTE(andreaf) The device name may be different on different guest OS
Evgeny Antyshev4894a912016-11-21 12:17:18 +000077 disks = self.linux_client.get_disks()
78 self.assertEqual(1, disks.count(CONF.compute.volume_device_name))
Masayuki Igawa73d9f3a2013-05-24 10:30:01 +090079
Jordan Pittier7cf64762015-10-14 15:01:12 +020080 def create_and_add_security_group_to_server(self, server):
Yair Fried1fc32a12014-08-04 09:11:30 +030081 secgroup = self._create_security_group()
Jordan Pittier7cf64762015-10-14 15:01:12 +020082 self.servers_client.add_security_group(server['id'],
Ken'ichi Ohmichie6349f32015-12-09 06:47:54 +000083 name=secgroup['name'])
Andrea Frittoli247058f2014-07-16 16:09:22 +010084 self.addCleanup(self.servers_client.remove_security_group,
Ken'ichi Ohmichi36b714c2015-12-09 08:12:47 +000085 server['id'], name=secgroup['name'])
Grishkin0f1e11c2014-05-04 20:44:52 +040086
Clark Boylanff31bcc2014-11-04 13:44:04 -080087 def wait_for_secgroup_add():
Jordan Pittier7cf64762015-10-14 15:01:12 +020088 body = (self.servers_client.show_server(server['id'])
ghanshyam0f825252015-08-25 16:02:50 +090089 ['server'])
Clark Boylanff31bcc2014-11-04 13:44:04 -080090 return {'name': secgroup['name']} in body['security_groups']
91
Jordan Pittier35a63752016-08-30 13:09:12 +020092 if not test_utils.call_until_true(wait_for_secgroup_add,
93 CONF.compute.build_timeout,
94 CONF.compute.build_interval):
Clark Boylanff31bcc2014-11-04 13:44:04 -080095 msg = ('Timed out waiting for adding security group %s to server '
Jordan Pittier7cf64762015-10-14 15:01:12 +020096 '%s' % (secgroup['id'], server['id']))
Clark Boylanff31bcc2014-11-04 13:44:04 -080097 raise exceptions.TimeoutException(msg)
98
Matt Riedemann8ca50562016-08-16 14:46:01 -040099 def _get_floating_ip_in_server_addresses(self, floating_ip, server):
Béla Vancsicsb6dfa082017-03-01 10:44:58 +0100100 for addresses in server['addresses'].values():
Matt Riedemann8ca50562016-08-16 14:46:01 -0400101 for address in addresses:
102 if (address['OS-EXT-IPS:type'] == 'floating' and
103 address['addr'] == floating_ip['ip']):
104 return address
105
Ken'ichi Ohmichic85a9512017-01-27 18:34:24 -0800106 @decorators.idempotent_id('bdbb5441-9204-419d-a225-b4fdbfb1a1a8')
Andrea Frittolicd368412017-08-14 21:37:56 +0100107 @utils.services('compute', 'volume', 'image', 'network')
Masayuki Igawa73d9f3a2013-05-24 10:30:01 +0900108 def test_minimum_basic_scenario(self):
Jordan Pittier1e443ec2015-11-20 16:15:58 +0100109 image = self.glance_image_create()
Jordan Pittier7cf64762015-10-14 15:01:12 +0200110 keypair = self.create_keypair()
JordanP3fe2dc32014-11-17 13:06:01 +0100111
zhufl13c9c892017-02-10 12:04:07 +0800112 server = self.create_server(image_id=image, key_name=keypair['name'])
Jordan Pittier93dffb72016-09-16 15:12:31 +0200113 servers = self.servers_client.list_servers()['servers']
Jordan Pittier7cf64762015-10-14 15:01:12 +0200114 self.assertIn(server['id'], [x['id'] for x in servers])
JordanP3fe2dc32014-11-17 13:06:01 +0100115
Jordan Pittier7cf64762015-10-14 15:01:12 +0200116 self.nova_show(server)
117
Jordan Pittierbbb17122016-01-26 17:10:55 +0100118 volume = self.create_volume()
119 volumes = self.volumes_client.list_volumes()['volumes']
Jordan Pittier7cf64762015-10-14 15:01:12 +0200120 self.assertIn(volume['id'], [x['id'] for x in volumes])
121
122 self.cinder_show(volume)
123
124 volume = self.nova_volume_attach(server, volume)
125 self.addCleanup(self.nova_volume_detach, server, volume)
126 self.cinder_show(volume)
127
zhufl1bdc3e72018-01-10 14:10:47 +0800128 floating_ip = None
Matt Riedemann8ca50562016-08-16 14:46:01 -0400129 server = self.servers_client.show_server(server['id'])['server']
zhufl1bdc3e72018-01-10 14:10:47 +0800130 if (CONF.network_feature_enabled.floating_ips and
131 CONF.network.floating_network_name):
132 floating_ip = self.create_floating_ip(server)
133 # fetch the server again to make sure the addresses were refreshed
134 # after associating the floating IP
Jakub Libosvarf979a042018-02-06 11:14:38 +0000135 server = self.servers_client.show_server(server['id'])['server']
zhufl1bdc3e72018-01-10 14:10:47 +0800136 address = self._get_floating_ip_in_server_addresses(
137 floating_ip, server)
138 self.assertIsNotNone(
139 address,
140 "Failed to find floating IP '%s' in server addresses: %s" %
141 (floating_ip['ip'], server['addresses']))
142 ssh_ip = floating_ip['ip']
143 else:
144 ssh_ip = self.get_server_ip(server)
Matt Riedemann8ca50562016-08-16 14:46:01 -0400145
Jordan Pittier7cf64762015-10-14 15:01:12 +0200146 self.create_and_add_security_group_to_server(server)
147
Alexander Gubanova5ab12e2015-11-17 18:18:46 +0200148 # check that we can SSH to the server before reboot
Jordan Pittier7cf64762015-10-14 15:01:12 +0200149 self.linux_client = self.get_remote_client(
zhufl1bdc3e72018-01-10 14:10:47 +0800150 ssh_ip, private_key=keypair['private_key'],
zhuflf52c7592017-05-25 13:55:24 +0800151 server=server)
Alexander Gubanova5ab12e2015-11-17 18:18:46 +0200152
Jordan Pittier7cf64762015-10-14 15:01:12 +0200153 self.nova_reboot(server)
154
Alexander Gubanova5ab12e2015-11-17 18:18:46 +0200155 # check that we can SSH to the server after reboot
156 # (both connections are part of the scenario)
Jordan Pittier7cf64762015-10-14 15:01:12 +0200157 self.linux_client = self.get_remote_client(
zhufl1bdc3e72018-01-10 14:10:47 +0800158 ssh_ip, private_key=keypair['private_key'],
zhuflf52c7592017-05-25 13:55:24 +0800159 server=server)
Alexander Gubanova5ab12e2015-11-17 18:18:46 +0200160
Evgeny Antyshev4894a912016-11-21 12:17:18 +0000161 self.check_disks()
Matt Riedemann8ca50562016-08-16 14:46:01 -0400162
zhufl1bdc3e72018-01-10 14:10:47 +0800163 if floating_ip:
164 # delete the floating IP, this should refresh the server addresses
165 self.compute_floating_ips_client.delete_floating_ip(
166 floating_ip['id'])
zhuflc310b8d2016-09-27 11:33:23 +0800167
zhufl1bdc3e72018-01-10 14:10:47 +0800168 def is_floating_ip_detached_from_server():
169 server_info = self.servers_client.show_server(
170 server['id'])['server']
171 address = self._get_floating_ip_in_server_addresses(
172 floating_ip, server_info)
173 return (not address)
zhuflc310b8d2016-09-27 11:33:23 +0800174
zhufl1bdc3e72018-01-10 14:10:47 +0800175 if not test_utils.call_until_true(
176 is_floating_ip_detached_from_server,
177 CONF.compute.build_timeout,
178 CONF.compute.build_interval):
179 msg = ("Floating IP '%s' should not be in server addresses: %s"
180 % (floating_ip['ip'], server['addresses']))
181 raise exceptions.TimeoutException(msg)