Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 1 | import base64 |
Daryl Walleck | b43ce8a | 2012-02-26 19:14:25 -0600 | [diff] [blame] | 2 | import time |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 3 | |
Brian Waldon | 738cd63 | 2011-12-12 18:45:09 -0500 | [diff] [blame] | 4 | from nose.plugins.attrib import attr |
| 5 | import unittest2 as unittest |
sapan-kona | f1e3f00 | 2011-12-22 23:18:44 +0530 | [diff] [blame] | 6 | from tempest import exceptions |
Brian Waldon | 738cd63 | 2011-12-12 18:45:09 -0500 | [diff] [blame] | 7 | from tempest.common.utils.data_utils import rand_name |
| 8 | import tempest.config |
| 9 | from tempest import openstack |
| 10 | |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 11 | |
| 12 | class ServerActionsTest(unittest.TestCase): |
Brian Waldon | 738cd63 | 2011-12-12 18:45:09 -0500 | [diff] [blame] | 13 | |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 14 | resize_available = tempest.config.TempestConfig().env.resize_available |
| 15 | |
| 16 | @classmethod |
| 17 | def setUpClass(cls): |
| 18 | cls.os = openstack.Manager() |
| 19 | cls.client = cls.os.servers_client |
| 20 | cls.config = cls.os.config |
| 21 | cls.image_ref = cls.config.env.image_ref |
| 22 | cls.image_ref_alt = cls.config.env.image_ref_alt |
| 23 | cls.flavor_ref = cls.config.env.flavor_ref |
| 24 | cls.flavor_ref_alt = cls.config.env.flavor_ref_alt |
Daryl Walleck | b43ce8a | 2012-02-26 19:14:25 -0600 | [diff] [blame] | 25 | cls.build_interval = cls.config.nova.build_interval |
| 26 | cls.build_timeout = cls.config.nova.build_timeout |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 27 | |
| 28 | def setUp(self): |
| 29 | self.name = rand_name('server') |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 30 | resp, server = self.client.create_server(self.name, |
| 31 | self.image_ref, |
| 32 | self.flavor_ref) |
| 33 | self.server_id = server['id'] |
| 34 | |
| 35 | self.client.wait_for_server_status(self.server_id, 'ACTIVE') |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 36 | |
| 37 | def tearDown(self): |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 38 | self.client.delete_server(self.server_id) |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 39 | |
| 40 | @attr(type='smoke') |
| 41 | def test_change_server_password(self): |
| 42 | """The server's password should be set to the provided password""" |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 43 | resp, body = self.client.change_password(self.server_id, 'newpass') |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 44 | self.assertEqual(202, resp.status) |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 45 | self.client.wait_for_server_status(self.server_id, 'ACTIVE') |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 46 | |
| 47 | @attr(type='smoke') |
| 48 | def test_reboot_server_hard(self): |
| 49 | """ The server should be power cycled """ |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 50 | resp, body = self.client.reboot(self.server_id, 'HARD') |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 51 | self.assertEqual(202, resp.status) |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 52 | self.client.wait_for_server_status(self.server_id, 'ACTIVE') |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 53 | |
| 54 | @attr(type='smoke') |
| 55 | def test_reboot_server_soft(self): |
| 56 | """The server should be signaled to reboot gracefully""" |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 57 | resp, body = self.client.reboot(self.server_id, 'SOFT') |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 58 | self.assertEqual(202, resp.status) |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 59 | self.client.wait_for_server_status(self.server_id, 'ACTIVE') |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 60 | |
| 61 | @attr(type='smoke') |
| 62 | def test_rebuild_server(self): |
| 63 | """ The server should be rebuilt using the provided image and data """ |
| 64 | meta = {'rebuild': 'server'} |
Brian Waldon | 738cd63 | 2011-12-12 18:45:09 -0500 | [diff] [blame] | 65 | new_name = rand_name('server') |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 66 | file_contents = 'Test server rebuild.' |
| 67 | personality = [{'path': '/etc/rebuild.txt', |
| 68 | 'contents': base64.b64encode(file_contents)}] |
| 69 | |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 70 | resp, rebuilt_server = self.client.rebuild(self.server_id, |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 71 | self.image_ref_alt, |
Brian Waldon | 738cd63 | 2011-12-12 18:45:09 -0500 | [diff] [blame] | 72 | name=new_name, meta=meta, |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 73 | personality=personality, |
| 74 | adminPass='rebuild') |
| 75 | |
| 76 | #Verify the properties in the initial response are correct |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 77 | self.assertEqual(self.server_id, rebuilt_server['id']) |
Eoghan Glynn | 57c1a3d | 2012-03-01 16:50:29 -0500 | [diff] [blame^] | 78 | rebuilt_image_id = rebuilt_server['image']['id'] |
| 79 | self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id)) |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 80 | self.assertEqual(self.flavor_ref, rebuilt_server['flavor']['id']) |
| 81 | |
| 82 | #Verify the server properties after the rebuild completes |
| 83 | self.client.wait_for_server_status(rebuilt_server['id'], 'ACTIVE') |
| 84 | resp, server = self.client.get_server(rebuilt_server['id']) |
Eoghan Glynn | 57c1a3d | 2012-03-01 16:50:29 -0500 | [diff] [blame^] | 85 | rebuilt_image_id = rebuilt_server['image']['id'] |
| 86 | self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id)) |
Brian Waldon | 738cd63 | 2011-12-12 18:45:09 -0500 | [diff] [blame] | 87 | self.assertEqual(new_name, rebuilt_server['name']) |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 88 | |
| 89 | @attr(type='smoke') |
| 90 | @unittest.skipIf(not resize_available, 'Resize not available.') |
| 91 | def test_resize_server_confirm(self): |
| 92 | """ |
| 93 | The server's RAM and disk space should be modified to that of |
| 94 | the provided flavor |
| 95 | """ |
| 96 | |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 97 | resp, server = self.client.resize(self.server_id, self.flavor_ref_alt) |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 98 | self.assertEqual(202, resp.status) |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 99 | self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE') |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 100 | |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 101 | self.client.confirm_resize(self.server_id) |
| 102 | self.client.wait_for_server_status(self.server_id, 'ACTIVE') |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 103 | |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 104 | resp, server = self.client.get_server(self.server_id) |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 105 | self.assertEqual(self.flavor_ref_alt, server['flavor']['id']) |
| 106 | |
| 107 | @attr(type='smoke') |
| 108 | @unittest.skipIf(not resize_available, 'Resize not available.') |
| 109 | def test_resize_server_revert(self): |
| 110 | """ |
| 111 | The server's RAM and disk space should return to its original |
| 112 | values after a resize is reverted |
| 113 | """ |
| 114 | |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 115 | resp, server = self.client.resize(self.server_id, self.flavor_ref_alt) |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 116 | self.assertEqual(202, resp.status) |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 117 | self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE') |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 118 | |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 119 | self.client.revert_resize(self.server_id) |
| 120 | self.client.wait_for_server_status(self.server_id, 'ACTIVE') |
Daryl Walleck | ed8bef3 | 2011-12-05 23:02:08 -0600 | [diff] [blame] | 121 | |
Daryl Walleck | b43ce8a | 2012-02-26 19:14:25 -0600 | [diff] [blame] | 122 | # Need to poll for the id change until lp#924371 is fixed |
Brian Waldon | 3bde07f | 2011-12-13 15:11:22 -0500 | [diff] [blame] | 123 | resp, server = self.client.get_server(self.server_id) |
Daryl Walleck | b43ce8a | 2012-02-26 19:14:25 -0600 | [diff] [blame] | 124 | start = int(time.time()) |
| 125 | |
| 126 | while server['flavor']['id'] != self.flavor_ref: |
| 127 | time.sleep(self.build_interval) |
| 128 | resp, server = self.client.get_server(self.server_id) |
| 129 | |
| 130 | if int(time.time()) - start >= self.build_timeout: |
| 131 | message = 'Server %s failed to revert resize within the \ |
| 132 | required time (%s s).' % (self.server_id, self.build_timeout) |
| 133 | raise exceptions.TimeoutException(message) |
sapan-kona | f1e3f00 | 2011-12-22 23:18:44 +0530 | [diff] [blame] | 134 | |
| 135 | @attr(type='negative') |
| 136 | def test_reboot_nonexistant_server_soft(self): |
| 137 | """ |
| 138 | Negative Test: The server reboot on non existant server should return |
| 139 | an error |
| 140 | """ |
David Kranz | 5a23d86 | 2012-02-14 09:48:55 -0500 | [diff] [blame] | 141 | self.assertRaises(exceptions.NotFound, self.client.reboot, 999, 'SOFT') |
sapan-kona | f1e3f00 | 2011-12-22 23:18:44 +0530 | [diff] [blame] | 142 | |
| 143 | @attr(type='negative') |
| 144 | def test_rebuild_nonexistant_server(self): |
| 145 | """ |
| 146 | Negative test: The server rebuild for a non existing server should not |
| 147 | be allowed |
| 148 | """ |
| 149 | meta = {'rebuild': 'server'} |
| 150 | new_name = rand_name('server') |
| 151 | file_contents = 'Test server rebuild.' |
| 152 | personality = [{'path': '/etc/rebuild.txt', |
| 153 | 'contents': base64.b64encode(file_contents)}] |
| 154 | try: |
| 155 | resp, rebuilt_server = self.client.rebuild(999, |
| 156 | self.image_ref_alt, name=new_name, |
| 157 | meta=meta, personality=personality, |
| 158 | adminPass='rebuild') |
| 159 | except exceptions.NotFound: |
| 160 | pass |
| 161 | else: |
| 162 | self.fail('The server rebuild for a non existing server should not' |
| 163 | ' be allowed') |