blob: dd6b02f24162c618234104eae83e7a1e03f139b8 [file] [log] [blame]
Jay Pipes13b479b2012-06-11 14:52:27 -04001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2012 OpenStack, LLC
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
Daryl Wallecked8bef32011-12-05 23:02:08 -060018import base64
Daryl Walleckb43ce8a2012-02-26 19:14:25 -060019import time
Brian Waldon738cd632011-12-12 18:45:09 -050020
Daryl Walleckc7251962012-03-12 17:26:54 -050021from nose.plugins.attrib import attr
Jay Pipes13b479b2012-06-11 14:52:27 -040022import unittest2 as unittest
23
24import tempest.config
25from tempest import exceptions
26from tempest.common.utils.data_utils import rand_name
Daryl Walleck98e66dd2012-06-21 04:58:39 -050027from tempest.common.utils.linux.remote_client import RemoteClient
Dan Smithbc3bd242012-08-14 09:48:48 -070028from tempest.tests.compute import base
David Kranzf97d5fd2012-07-30 13:46:45 -040029from tempest.tests import compute
Daryl Wallecked8bef32011-12-05 23:02:08 -060030
Daryl Walleckc7251962012-03-12 17:26:54 -050031
Dan Smithbc3bd242012-08-14 09:48:48 -070032class ServerActionsTestBase(object):
Brian Waldon738cd632011-12-12 18:45:09 -050033
Daryl Walleck587385b2012-03-03 13:00:26 -060034 resize_available = tempest.config.TempestConfig().compute.resize_available
Daryl Walleck98e66dd2012-06-21 04:58:39 -050035 run_ssh = tempest.config.TempestConfig().compute.run_ssh
Daryl Wallecked8bef32011-12-05 23:02:08 -060036
Daryl Wallecked8bef32011-12-05 23:02:08 -060037 def setUp(self):
38 self.name = rand_name('server')
Brian Waldon3bde07f2011-12-13 15:11:22 -050039 resp, server = self.client.create_server(self.name,
40 self.image_ref,
41 self.flavor_ref)
42 self.server_id = server['id']
Daryl Walleck98e66dd2012-06-21 04:58:39 -050043 self.password = server['adminPass']
Brian Waldon3bde07f2011-12-13 15:11:22 -050044 self.client.wait_for_server_status(self.server_id, 'ACTIVE')
Daryl Wallecked8bef32011-12-05 23:02:08 -060045
46 def tearDown(self):
Brian Waldon3bde07f2011-12-13 15:11:22 -050047 self.client.delete_server(self.server_id)
Daryl Wallecked8bef32011-12-05 23:02:08 -060048
49 @attr(type='smoke')
David Kranzf97d5fd2012-07-30 13:46:45 -040050 @unittest.skipUnless(compute.CHANGE_PASSWORD_AVAILABLE,
51 'Change password not available.')
Daryl Wallecked8bef32011-12-05 23:02:08 -060052 def test_change_server_password(self):
53 """The server's password should be set to the provided password"""
Daryl Walleck98e66dd2012-06-21 04:58:39 -050054 new_password = 'Newpass1234'
55 resp, body = self.client.change_password(self.server_id, new_password)
Daryl Wallecked8bef32011-12-05 23:02:08 -060056 self.assertEqual(202, resp.status)
Brian Waldon3bde07f2011-12-13 15:11:22 -050057 self.client.wait_for_server_status(self.server_id, 'ACTIVE')
Daryl Wallecked8bef32011-12-05 23:02:08 -060058
Daryl Walleck98e66dd2012-06-21 04:58:39 -050059 if self.run_ssh:
60 # Verify that the user can authenticate with the new password
61 resp, server = self.client.get_server(self.server_id)
62 linux_client = RemoteClient(server, self.ssh_user, new_password)
63 self.assertTrue(linux_client.can_authenticate())
64
Daryl Wallecked8bef32011-12-05 23:02:08 -060065 @attr(type='smoke')
66 def test_reboot_server_hard(self):
67 """ The server should be power cycled """
Daryl Walleck98e66dd2012-06-21 04:58:39 -050068 if self.run_ssh:
69 # Get the time the server was last rebooted,
70 # waiting for one minute as who doesn't have seconds precision
71 resp, server = self.client.get_server(self.server_id)
72 linux_client = RemoteClient(server, self.ssh_user, self.password)
73 boot_time = linux_client.get_boot_time()
74 time.sleep(60)
75
Brian Waldon3bde07f2011-12-13 15:11:22 -050076 resp, body = self.client.reboot(self.server_id, 'HARD')
Daryl Wallecked8bef32011-12-05 23:02:08 -060077 self.assertEqual(202, resp.status)
Brian Waldon3bde07f2011-12-13 15:11:22 -050078 self.client.wait_for_server_status(self.server_id, 'ACTIVE')
Daryl Wallecked8bef32011-12-05 23:02:08 -060079
Daryl Walleck98e66dd2012-06-21 04:58:39 -050080 if self.run_ssh:
81 # Log in and verify the boot time has changed
82 linux_client = RemoteClient(server, self.ssh_user, self.password)
83 new_boot_time = linux_client.get_boot_time()
84 self.assertGreater(new_boot_time, boot_time)
85
Daryl Wallecked8bef32011-12-05 23:02:08 -060086 @attr(type='smoke')
David Kranz9b6129c2012-06-25 12:10:48 -040087 @unittest.skip('Until bug 1014647 is dealt with.')
Daryl Wallecked8bef32011-12-05 23:02:08 -060088 def test_reboot_server_soft(self):
89 """The server should be signaled to reboot gracefully"""
Daryl Walleck98e66dd2012-06-21 04:58:39 -050090 if self.run_ssh:
91 # Get the time the server was last rebooted,
92 # waiting for one minute as who doesn't have seconds precision
93 resp, server = self.client.get_server(self.server_id)
94 linux_client = RemoteClient(server, self.ssh_user, self.password)
95 boot_time = linux_client.get_boot_time()
96 time.sleep(60)
97
Brian Waldon3bde07f2011-12-13 15:11:22 -050098 resp, body = self.client.reboot(self.server_id, 'SOFT')
Daryl Wallecked8bef32011-12-05 23:02:08 -060099 self.assertEqual(202, resp.status)
Brian Waldon3bde07f2011-12-13 15:11:22 -0500100 self.client.wait_for_server_status(self.server_id, 'ACTIVE')
Daryl Wallecked8bef32011-12-05 23:02:08 -0600101
Daryl Walleck98e66dd2012-06-21 04:58:39 -0500102 if self.run_ssh:
103 # Log in and verify the boot time has changed
104 linux_client = RemoteClient(server, self.ssh_user, self.password)
105 new_boot_time = linux_client.get_boot_time()
106 self.assertGreater(new_boot_time, boot_time)
107
Daryl Wallecked8bef32011-12-05 23:02:08 -0600108 @attr(type='smoke')
109 def test_rebuild_server(self):
110 """ The server should be rebuilt using the provided image and data """
111 meta = {'rebuild': 'server'}
Brian Waldon738cd632011-12-12 18:45:09 -0500112 new_name = rand_name('server')
Daryl Wallecked8bef32011-12-05 23:02:08 -0600113 file_contents = 'Test server rebuild.'
114 personality = [{'path': '/etc/rebuild.txt',
115 'contents': base64.b64encode(file_contents)}]
Daryl Walleck98e66dd2012-06-21 04:58:39 -0500116 password = 'rebuildPassw0rd'
Brian Waldon3bde07f2011-12-13 15:11:22 -0500117 resp, rebuilt_server = self.client.rebuild(self.server_id,
Daryl Wallecked8bef32011-12-05 23:02:08 -0600118 self.image_ref_alt,
Brian Waldon738cd632011-12-12 18:45:09 -0500119 name=new_name, meta=meta,
Daryl Wallecked8bef32011-12-05 23:02:08 -0600120 personality=personality,
Daryl Walleck98e66dd2012-06-21 04:58:39 -0500121 adminPass=password)
Daryl Wallecked8bef32011-12-05 23:02:08 -0600122
123 #Verify the properties in the initial response are correct
Brian Waldon3bde07f2011-12-13 15:11:22 -0500124 self.assertEqual(self.server_id, rebuilt_server['id'])
Eoghan Glynn57c1a3d2012-03-01 16:50:29 -0500125 rebuilt_image_id = rebuilt_server['image']['id']
126 self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id))
Daryl Wallecked8bef32011-12-05 23:02:08 -0600127 self.assertEqual(self.flavor_ref, rebuilt_server['flavor']['id'])
128
129 #Verify the server properties after the rebuild completes
130 self.client.wait_for_server_status(rebuilt_server['id'], 'ACTIVE')
131 resp, server = self.client.get_server(rebuilt_server['id'])
Eoghan Glynn57c1a3d2012-03-01 16:50:29 -0500132 rebuilt_image_id = rebuilt_server['image']['id']
133 self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id))
Brian Waldon738cd632011-12-12 18:45:09 -0500134 self.assertEqual(new_name, rebuilt_server['name'])
Daryl Wallecked8bef32011-12-05 23:02:08 -0600135
Daryl Walleck98e66dd2012-06-21 04:58:39 -0500136 if self.run_ssh:
137 # Verify that the user can authenticate with the provided password
138 linux_client = RemoteClient(server, self.ssh_user, password)
139 self.assertTrue(linux_client.can_authenticate())
140
Daryl Wallecked8bef32011-12-05 23:02:08 -0600141 @attr(type='smoke')
142 @unittest.skipIf(not resize_available, 'Resize not available.')
143 def test_resize_server_confirm(self):
144 """
145 The server's RAM and disk space should be modified to that of
146 the provided flavor
147 """
148
Brian Waldon3bde07f2011-12-13 15:11:22 -0500149 resp, server = self.client.resize(self.server_id, self.flavor_ref_alt)
Daryl Wallecked8bef32011-12-05 23:02:08 -0600150 self.assertEqual(202, resp.status)
Brian Waldon3bde07f2011-12-13 15:11:22 -0500151 self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
Daryl Wallecked8bef32011-12-05 23:02:08 -0600152
Brian Waldon3bde07f2011-12-13 15:11:22 -0500153 self.client.confirm_resize(self.server_id)
154 self.client.wait_for_server_status(self.server_id, 'ACTIVE')
Daryl Wallecked8bef32011-12-05 23:02:08 -0600155
Brian Waldon3bde07f2011-12-13 15:11:22 -0500156 resp, server = self.client.get_server(self.server_id)
Daryl Wallecked8bef32011-12-05 23:02:08 -0600157 self.assertEqual(self.flavor_ref_alt, server['flavor']['id'])
158
Daryl Wallecked97dca2012-07-04 23:25:45 -0500159 @attr(type='positive')
Daryl Wallecked8bef32011-12-05 23:02:08 -0600160 @unittest.skipIf(not resize_available, 'Resize not available.')
161 def test_resize_server_revert(self):
162 """
163 The server's RAM and disk space should return to its original
164 values after a resize is reverted
165 """
166
Brian Waldon3bde07f2011-12-13 15:11:22 -0500167 resp, server = self.client.resize(self.server_id, self.flavor_ref_alt)
Daryl Wallecked8bef32011-12-05 23:02:08 -0600168 self.assertEqual(202, resp.status)
Brian Waldon3bde07f2011-12-13 15:11:22 -0500169 self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
Daryl Wallecked8bef32011-12-05 23:02:08 -0600170
Brian Waldon3bde07f2011-12-13 15:11:22 -0500171 self.client.revert_resize(self.server_id)
172 self.client.wait_for_server_status(self.server_id, 'ACTIVE')
Daryl Wallecked8bef32011-12-05 23:02:08 -0600173
Daryl Walleckb43ce8a2012-02-26 19:14:25 -0600174 # Need to poll for the id change until lp#924371 is fixed
Brian Waldon3bde07f2011-12-13 15:11:22 -0500175 resp, server = self.client.get_server(self.server_id)
Daryl Walleckb43ce8a2012-02-26 19:14:25 -0600176 start = int(time.time())
177
178 while server['flavor']['id'] != self.flavor_ref:
179 time.sleep(self.build_interval)
180 resp, server = self.client.get_server(self.server_id)
181
182 if int(time.time()) - start >= self.build_timeout:
183 message = 'Server %s failed to revert resize within the \
184 required time (%s s).' % (self.server_id, self.build_timeout)
185 raise exceptions.TimeoutException(message)
sapan-konaf1e3f002011-12-22 23:18:44 +0530186
187 @attr(type='negative')
Joe Gordonddf39272012-09-13 15:04:55 -0700188 def test_reboot_nonexistent_server_soft(self):
sapan-konaf1e3f002011-12-22 23:18:44 +0530189 """
Joe Gordonddf39272012-09-13 15:04:55 -0700190 Negative Test: The server reboot on non existent server should return
sapan-konaf1e3f002011-12-22 23:18:44 +0530191 an error
192 """
David Kranz5a23d862012-02-14 09:48:55 -0500193 self.assertRaises(exceptions.NotFound, self.client.reboot, 999, 'SOFT')
sapan-konaf1e3f002011-12-22 23:18:44 +0530194
195 @attr(type='negative')
Joe Gordonddf39272012-09-13 15:04:55 -0700196 def test_rebuild_nonexistent_server(self):
sapan-konaf1e3f002011-12-22 23:18:44 +0530197 """
198 Negative test: The server rebuild for a non existing server should not
199 be allowed
200 """
201 meta = {'rebuild': 'server'}
202 new_name = rand_name('server')
203 file_contents = 'Test server rebuild.'
204 personality = [{'path': '/etc/rebuild.txt',
205 'contents': base64.b64encode(file_contents)}]
206 try:
207 resp, rebuilt_server = self.client.rebuild(999,
Zhongyue Luo79d8d362012-09-25 13:49:27 +0800208 self.image_ref_alt,
209 name=new_name,
210 meta=meta,
211 personality=personality,
212 adminPass='rebuild')
sapan-konaf1e3f002011-12-22 23:18:44 +0530213 except exceptions.NotFound:
214 pass
215 else:
216 self.fail('The server rebuild for a non existing server should not'
217 ' be allowed')
Dan Smithbc3bd242012-08-14 09:48:48 -0700218
219
220class ServerActionsTestXML(base.BaseComputeTestXML,
221 ServerActionsTestBase):
222 @classmethod
223 def setUpClass(cls):
224 super(ServerActionsTestXML, cls).setUpClass()
225 cls.client = cls.servers_client
226
227 def setUp(self):
228 ServerActionsTestBase.setUp(self)
229
230 def tearDown(self):
231 ServerActionsTestBase.tearDown(self)
232
233
234class ServerActionsTestJSON(base.BaseComputeTestJSON,
235 ServerActionsTestBase):
236 @classmethod
237 def setUpClass(cls):
238 super(ServerActionsTestJSON, cls).setUpClass()
239 cls.client = cls.servers_client
240
241 def setUp(self):
242 ServerActionsTestBase.setUp(self)
243
244 def tearDown(self):
245 ServerActionsTestBase.tearDown(self)