blob: fcf60d11df55d6a50611a99ef487841f25875c4b [file] [log] [blame]
Soren Hansenbc1d3a02011-09-08 13:33:17 +02001
2import json
3import time
4
5from kong import exceptions
6from kong import openstack
Soren Hansen6adacc82011-09-09 13:34:35 +02007from kong import tests
Soren Hansenbc1d3a02011-09-08 13:33:17 +02008from kong.common import ssh
9
10import unittest2 as unittest
11
12
Soren Hansen6adacc82011-09-09 13:34:35 +020013class ServerActionsTest(tests.FunctionalTest):
Soren Hansenbc1d3a02011-09-08 13:33:17 +020014
Soren Hansenbc1d3a02011-09-08 13:33:17 +020015 def setUp(self):
Soren Hansen6adacc82011-09-09 13:34:35 +020016 super(ServerActionsTest, self).setUp()
Soren Hansend6b047a2011-09-09 13:39:32 +020017 self.os = openstack.Manager(self.nova)
Soren Hansenbc1d3a02011-09-08 13:33:17 +020018
Brian Waldon883cb262011-11-02 11:30:07 -040019 self.multi_node = self.nova['multi_node'] == 'yes'
Soren Hansena86180a2011-09-09 16:22:26 +020020 self.image_ref = self.glance['image_id']
Brian Waldon883cb262011-11-02 11:30:07 -040021 self.image_ref_alt = self.glance['image_id_alt']
Soren Hansena86180a2011-09-09 16:22:26 +020022 self.flavor_ref = self.nova['flavor_ref']
23 self.flavor_ref_alt = self.nova['flavor_ref_alt']
Brian Waldon883cb262011-11-02 11:30:07 -040024 self.ssh_timeout = int(self.nova['ssh_timeout'])
25 self.build_timeout = int(self.nova['build_timeout'])
Soren Hansenbc1d3a02011-09-08 13:33:17 +020026
27 self.server_password = 'testpwd'
Soren Hansen5f4ad832011-09-09 14:08:19 +020028 self.server_name = 'stacktester1'
Soren Hansenbc1d3a02011-09-08 13:33:17 +020029
30 expected_server = {
Soren Hansen5f4ad832011-09-09 14:08:19 +020031 'name': self.server_name,
32 'imageRef': self.image_ref,
33 'flavorRef': self.flavor_ref,
34 'adminPass': self.server_password,
Soren Hansenbc1d3a02011-09-08 13:33:17 +020035 }
36
37 created_server = self.os.nova.create_server(expected_server)
38
39 self.server_id = created_server['id']
Soren Hansen5f4ad832011-09-09 14:08:19 +020040 self._wait_for_server_status(self.server_id, 'ACTIVE')
Soren Hansenbc1d3a02011-09-08 13:33:17 +020041
42 server = self.os.nova.get_server(self.server_id)
Soren Hansenbc1d3a02011-09-08 13:33:17 +020043 self.access_ip = server['addresses']['public'][0]['addr']
44
45 # Ensure server came up
Brian Waldon883cb262011-11-02 11:30:07 -040046 if self.ssh_timeout:
47 self._assert_ssh_password()
Soren Hansenbc1d3a02011-09-08 13:33:17 +020048
49 def tearDown(self):
50 self.os.nova.delete_server(self.server_id)
51
52 def _get_ssh_client(self, password):
53 return ssh.Client(self.access_ip, 'root', password, self.ssh_timeout)
54
55 def _assert_ssh_password(self, password=None):
56 _password = password or self.server_password
57 client = self._get_ssh_client(_password)
58 self.assertTrue(client.test_connection_auth())
59
Soren Hansen5f4ad832011-09-09 14:08:19 +020060 def _wait_for_server_status(self, server_id, status):
Soren Hansenbc1d3a02011-09-08 13:33:17 +020061 try:
Soren Hansen5f4ad832011-09-09 14:08:19 +020062 self.os.nova.wait_for_server_status(server_id, status,
63 timeout=self.build_timeout)
Soren Hansenbc1d3a02011-09-08 13:33:17 +020064 except exceptions.TimeoutException:
65 self.fail("Server failed to change status to %s" % status)
66
67 def _get_boot_time(self):
68 """Return the time the server was started"""
69 output = self._read_file("/proc/uptime")
70 uptime = float(output.split().pop(0))
71 return time.time() - uptime
72
Soren Hansen5f4ad832011-09-09 14:08:19 +020073 def _write_file(self, filename, contents, password=None):
74 command = "echo -n %s > %s" % (contents, filename)
75 return self._exec_command(command, password)
Soren Hansenbc1d3a02011-09-08 13:33:17 +020076
Soren Hansen5f4ad832011-09-09 14:08:19 +020077 def _read_file(self, filename, password=None):
78 command = "cat %s" % filename
79 return self._exec_command(command, password)
Soren Hansenbc1d3a02011-09-08 13:33:17 +020080
Soren Hansen5f4ad832011-09-09 14:08:19 +020081 def _exec_command(self, command, password=None):
82 if password is None:
83 password = self.server_password
84 client = self._get_ssh_client(password)
Soren Hansenbc1d3a02011-09-08 13:33:17 +020085 return client.exec_command(command)
86
Brian Waldon883cb262011-11-02 11:30:07 -040087 def test_reboot_server(self):
88 """Reboot a server SOFT and HARD"""
Soren Hansenbc1d3a02011-09-08 13:33:17 +020089 # SSH and get the uptime
Brian Waldon883cb262011-11-02 11:30:07 -040090 if self.ssh_timeout:
91 initial_time_started = self._get_boot_time()
92 else:
93 intitial_time_started = 0
Soren Hansenbc1d3a02011-09-08 13:33:17 +020094
95 # Make reboot request
Soren Hansen5f4ad832011-09-09 14:08:19 +020096 post_body = json.dumps({'reboot': {'type': 'SOFT'}})
Soren Hansenbc1d3a02011-09-08 13:33:17 +020097 url = "/servers/%s/action" % self.server_id
98 response, body = self.os.nova.request('POST', url, body=post_body)
99 self.assertEqual(response['status'], '202')
100
101 # Assert status transition
Brian Waldon883cb262011-11-02 11:30:07 -0400102 self._wait_for_server_status(self.server_id, 'REBOOT')
Soren Hansen5f4ad832011-09-09 14:08:19 +0200103 self._wait_for_server_status(self.server_id, 'ACTIVE')
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200104
105 # SSH and verify uptime is less than before
Brian Waldon883cb262011-11-02 11:30:07 -0400106 if self.ssh_timeout:
107 post_reboot_time_started = self._get_boot_time()
108 self.assertTrue(initial_time_started < post_reboot_time_started)
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200109
Brian Waldon883cb262011-11-02 11:30:07 -0400110 # SSH and get the uptime for the next reboot
111 initial_time_started = post_reboot_time_started
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200112
113 # Make reboot request
Soren Hansen5f4ad832011-09-09 14:08:19 +0200114 post_body = json.dumps({'reboot': {'type': 'HARD'}})
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200115 url = "/servers/%s/action" % self.server_id
116 response, body = self.os.nova.request('POST', url, body=post_body)
117 self.assertEqual(response['status'], '202')
118
119 # Assert status transition
Brian Waldon883cb262011-11-02 11:30:07 -0400120 # KNOWN-ISSUE 884906
Soren Hansen5f4ad832011-09-09 14:08:19 +0200121 #self._wait_for_server_status(self.server_id, 'HARD_REBOOT')
Brian Waldon883cb262011-11-02 11:30:07 -0400122 self._wait_for_server_status(self.server_id, 'REBOOT')
Soren Hansen5f4ad832011-09-09 14:08:19 +0200123 self._wait_for_server_status(self.server_id, 'ACTIVE')
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200124
125 # SSH and verify uptime is less than before
Brian Waldon883cb262011-11-02 11:30:07 -0400126 if self.ssh_timeout:
127 post_reboot_time_started = self._get_boot_time()
128 self.assertTrue(initial_time_started < post_reboot_time_started)
129 test_reboot_server.tags = ['nova']
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200130
Brian Waldon883cb262011-11-02 11:30:07 -0400131 def test_change_password(self):
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200132 """Change root password of a server"""
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200133 # Change server password
Soren Hansen5f4ad832011-09-09 14:08:19 +0200134 post_body = json.dumps({'changePassword': {'adminPass': 'test123'}})
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200135 url = '/servers/%s/action' % self.server_id
136 response, body = self.os.nova.request('POST', url, body=post_body)
137
138 # Assert status transition
139 self.assertEqual('202', response['status'])
Soren Hansen5f4ad832011-09-09 14:08:19 +0200140 self._wait_for_server_status(self.server_id, 'PASSWORD')
141 self._wait_for_server_status(self.server_id, 'ACTIVE')
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200142
143 # SSH into server using new password
Brian Waldon883cb262011-11-02 11:30:07 -0400144 if self.ssh_timeout:
145 self._assert_ssh_password('test123')
146 test_change_password.tags = ['nova']
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200147
Soren Hansen5f4ad832011-09-09 14:08:19 +0200148 def test_rebuild(self):
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200149 """Rebuild a server"""
150
Soren Hansen5f4ad832011-09-09 14:08:19 +0200151 FILENAME = '/tmp/testfile'
152 CONTENTS = 'WORDS'
153
154 # write file to server
Brian Waldon883cb262011-11-02 11:30:07 -0400155 if self.ssh_timeout:
156 self._write_file(FILENAME, CONTENTS)
157 self.assertEqual(self._read_file(FILENAME), CONTENTS)
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200158
159 # Make rebuild request
Soren Hansen5f4ad832011-09-09 14:08:19 +0200160 post_body = json.dumps({'rebuild': {'imageRef': self.image_ref_alt}})
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200161 url = '/servers/%s/action' % self.server_id
162 response, body = self.os.nova.request('POST', url, body=post_body)
163
Soren Hansen5f4ad832011-09-09 14:08:19 +0200164 # check output
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200165 self.assertEqual('202', response['status'])
Soren Hansen5f4ad832011-09-09 14:08:19 +0200166 rebuilt_server = json.loads(body)['server']
167 generated_password = rebuilt_server['adminPass']
168
169 # Ensure correct status transition
Brian Waldon883cb262011-11-02 11:30:07 -0400170 self._wait_for_server_status(self.server_id, 'REBUILD')
Soren Hansen5f4ad832011-09-09 14:08:19 +0200171 self._wait_for_server_status(self.server_id, 'ACTIVE')
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200172
173 # Treats an issue where we ssh'd in too soon after rebuild
Brian Waldon883cb262011-11-02 11:30:07 -0400174 #TODO(bcwaldon): fix the Xen driver so we don't have to sleep here
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200175 time.sleep(30)
176
177 # Check that the instance's imageRef matches the new imageRef
178 server = self.os.nova.get_server(self.server_id)
179 ref_match = self.image_ref_alt == server['image']['links'][0]['href']
180 id_match = self.image_ref_alt == server['image']['id']
181 self.assertTrue(ref_match or id_match)
182
183 # SSH into the server to ensure it came back up
Brian Waldon883cb262011-11-02 11:30:07 -0400184 if self.ssh_timeout:
185 self._assert_ssh_password(generated_password)
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200186
Brian Waldon883cb262011-11-02 11:30:07 -0400187 # make sure file is gone
188 self.assertEqual(self._read_file(FILENAME, generated_password), '')
Soren Hansen5f4ad832011-09-09 14:08:19 +0200189
Brian Waldon883cb262011-11-02 11:30:07 -0400190 # test again with a specified password
191 self._write_file(FILENAME, CONTENTS, generated_password)
192 _contents = self._read_file(FILENAME, generated_password)
193 self.assertEqual(_contents, CONTENTS)
Soren Hansen5f4ad832011-09-09 14:08:19 +0200194
195 specified_password = 'some_password'
196
197 # Make rebuild request
198 post_body = json.dumps({
199 'rebuild': {
200 'imageRef': self.image_ref,
201 'adminPass': specified_password,
202 }
203 })
204 url = '/servers/%s/action' % self.server_id
205 response, body = self.os.nova.request('POST', url, body=post_body)
206
207 # check output
208 self.assertEqual('202', response['status'])
209 rebuilt_server = json.loads(body)['server']
210 self.assertEqual(rebuilt_server['adminPass'], specified_password)
211
212 # Ensure correct status transition
Brian Waldon883cb262011-11-02 11:30:07 -0400213 self._wait_for_server_status(self.server_id, 'REBUILD')
Soren Hansen5f4ad832011-09-09 14:08:19 +0200214 self._wait_for_server_status(self.server_id, 'ACTIVE')
215
216 # Treats an issue where we ssh'd in too soon after rebuild
217 time.sleep(30)
218
219 # Check that the instance's imageRef matches the new imageRef
220 server = self.os.nova.get_server(self.server_id)
221 ref_match = self.image_ref == server['image']['links'][0]['href']
222 id_match = self.image_ref == server['image']['id']
223 self.assertTrue(ref_match or id_match)
224
Soren Hansen5f4ad832011-09-09 14:08:19 +0200225 # make sure file is gone
Brian Waldon883cb262011-11-02 11:30:07 -0400226 if self.ssh_timeout:
227 self.assertEqual(self._read_file(FILENAME, specified_password), '')
Soren Hansenfce58c52011-09-09 16:07:13 +0200228 test_rebuild.tags = ['nova']
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200229
Brian Waldon883cb262011-11-02 11:30:07 -0400230 def test_resize(self):
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200231 """Resize a server"""
Brian Waldon883cb262011-11-02 11:30:07 -0400232
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200233 # Make resize request
Soren Hansen5f4ad832011-09-09 14:08:19 +0200234 post_body = json.dumps({'resize': {'flavorRef': self.flavor_ref_alt}})
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200235 url = '/servers/%s/action' % self.server_id
236 response, body = self.os.nova.request('POST', url, body=post_body)
237
238 # Wait for status transition
239 self.assertEqual('202', response['status'])
Brian Waldon883cb262011-11-02 11:30:07 -0400240 self._wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200241
242 # Ensure API reports new flavor
243 server = self.os.nova.get_server(self.server_id)
244 self.assertEqual(self.flavor_ref_alt, server['flavor']['id'])
245
246 #SSH into the server to ensure it came back up
Brian Waldon883cb262011-11-02 11:30:07 -0400247 if self.ssh_timeout:
248 self._assert_ssh_password()
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200249
250 # Make confirmResize request
Soren Hansen5f4ad832011-09-09 14:08:19 +0200251 post_body = json.dumps({'confirmResize': 'null'})
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200252 url = '/servers/%s/action' % self.server_id
253 response, body = self.os.nova.request('POST', url, body=post_body)
254
255 # Wait for status transition
256 self.assertEqual('204', response['status'])
Soren Hansen5f4ad832011-09-09 14:08:19 +0200257 self._wait_for_server_status(self.server_id, 'ACTIVE')
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200258
259 # Ensure API still reports new flavor
260 server = self.os.nova.get_server(self.server_id)
261 self.assertEqual(self.flavor_ref_alt, server['flavor']['id'])
Brian Waldon883cb262011-11-02 11:30:07 -0400262 test_resize.tags = ['nova']
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200263
Brian Waldon883cb262011-11-02 11:30:07 -0400264 def test_resize_revert(self):
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200265 """Resize a server, then revert"""
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200266 # Make resize request
Soren Hansen5f4ad832011-09-09 14:08:19 +0200267 post_body = json.dumps({'resize': {'flavorRef': self.flavor_ref_alt}})
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200268 url = '/servers/%s/action' % self.server_id
269 response, body = self.os.nova.request('POST', url, body=post_body)
270
271 # Wait for status transition
272 self.assertEqual('202', response['status'])
Brian Waldon883cb262011-11-02 11:30:07 -0400273 self._wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200274
275 # SSH into the server to ensure it came back up
Brian Waldon883cb262011-11-02 11:30:07 -0400276 if self.ssh_timeout:
277 self._assert_ssh_password()
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200278
279 # Ensure API reports new flavor
280 server = self.os.nova.get_server(self.server_id)
281 self.assertEqual(self.flavor_ref_alt, server['flavor']['id'])
282
283 # Make revertResize request
Soren Hansen5f4ad832011-09-09 14:08:19 +0200284 post_body = json.dumps({'revertResize': 'null'})
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200285 url = '/servers/%s/action' % self.server_id
286 response, body = self.os.nova.request('POST', url, body=post_body)
287
288 # Assert status transition
289 self.assertEqual('202', response['status'])
Soren Hansen5f4ad832011-09-09 14:08:19 +0200290 self._wait_for_server_status(self.server_id, 'ACTIVE')
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200291
292 # Ensure flavor ref was reverted to original
293 server = self.os.nova.get_server(self.server_id)
294 self.assertEqual(self.flavor_ref, server['flavor']['id'])
Brian Waldon883cb262011-11-02 11:30:07 -0400295 test_resize_revert.tags = ['nova']
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200296
297
Brian Waldon883cb262011-11-02 11:30:07 -0400298class SnapshotTests(tests.FunctionalTest):
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200299
300 def setUp(self):
Brian Waldon883cb262011-11-02 11:30:07 -0400301 super(SnapshotTests, self).setUp()
302 self.os = openstack.Manager(self.nova)
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200303
Brian Waldon883cb262011-11-02 11:30:07 -0400304 self.image_ref = self.glance['image_id']
305 self.flavor_ref = self.nova['flavor_ref']
306 self.ssh_timeout = int(self.nova['ssh_timeout'])
307 self.build_timeout = int(self.nova['build_timeout'])
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200308
Soren Hansen5f4ad832011-09-09 14:08:19 +0200309 self.server_name = 'stacktester1'
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200310
311 expected_server = {
Soren Hansen5f4ad832011-09-09 14:08:19 +0200312 'name': self.server_name,
313 'imageRef': self.image_ref,
314 'flavorRef': self.flavor_ref,
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200315 }
316
317 created_server = self.os.nova.create_server(expected_server)
318 self.server_id = created_server['id']
319
320 def tearDown(self):
321 self.os.nova.delete_server(self.server_id)
322
Soren Hansen5f4ad832011-09-09 14:08:19 +0200323 def _wait_for_server_status(self, server_id, status):
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200324 try:
Soren Hansen5f4ad832011-09-09 14:08:19 +0200325 self.os.nova.wait_for_server_status(server_id, status,
326 timeout=self.build_timeout)
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200327 except exceptions.TimeoutException:
328 self.fail("Server failed to change status to %s" % status)
329
Brian Waldon883cb262011-11-02 11:30:07 -0400330 def test_snapshot(self):
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200331 """Create image from an existing server"""
332
333 # Wait for server to come up before running this test
Soren Hansen5f4ad832011-09-09 14:08:19 +0200334 self._wait_for_server_status(self.server_id, 'ACTIVE')
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200335
336 # Create snapshot
Brian Waldon883cb262011-11-02 11:30:07 -0400337 image_data = {'name': 'testserver_snapshot'}
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200338 req_body = json.dumps({'createImage': image_data})
339 url = '/servers/%s/action' % self.server_id
340 response, body = self.os.nova.request('POST', url, body=req_body)
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200341 self.assertEqual(response['status'], '202')
342 image_ref = response['location']
Soren Hansen5f4ad832011-09-09 14:08:19 +0200343 snapshot_id = image_ref.rsplit('/', 1)[1]
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200344
345 # Get snapshot and check its attributes
346 resp, body = self.os.nova.request('GET', '/images/%s' % snapshot_id)
347 snapshot = json.loads(body)['image']
348 self.assertEqual(snapshot['name'], image_data['name'])
349 server_ref = snapshot['server']['links'][0]['href']
350 self.assertTrue(server_ref.endswith('/%s' % self.server_id))
351
Brian Waldon883cb262011-11-02 11:30:07 -0400352 # Wait for first snapshot to start saving before making second snapshot
353 self.os.nova.wait_for_image_status(snapshot['id'], 'SAVING')
354
355 # Create second snapshot
356 image_data = {'name': 'testserver_snapshot2'}
357 req_body = json.dumps({'createImage': image_data})
358 url = '/servers/%s/action' % self.server_id
359 response, body = self.os.nova.request('POST', url, body=req_body)
360 self.assertEqual(response['status'], '409')
361
362 # Ensure both snapshots succeed
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200363 self.os.nova.wait_for_image_status(snapshot['id'], 'ACTIVE')
364
365 # Cleaning up
366 self.os.nova.request('DELETE', '/images/%s' % snapshot_id)
Brian Waldon883cb262011-11-02 11:30:07 -0400367 test_snapshot.tags = ['nova']
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200368
Brian Waldon883cb262011-11-02 11:30:07 -0400369 def test_snapshot_while_building(self):
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200370 """Ensure inability to snapshot server in BUILD state"""
371
Brian Waldon883cb262011-11-02 11:30:07 -0400372 # Ensure server is in BUILD state
373 url = '/servers/%s' % self.server_id
374 response, body = self.os.nova.request('GET', url)
375 server = json.loads(body)['server']
376 self.assertEqual(server['status'], 'BUILD', 'Server built too quickly')
377
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200378 # Create snapshot
Brian Waldon883cb262011-11-02 11:30:07 -0400379 req_body = json.dumps({'createImage': {'name': 'testserver_snapshot'}})
Soren Hansenbc1d3a02011-09-08 13:33:17 +0200380 url = '/servers/%s/action' % self.server_id
381 response, body = self.os.nova.request('POST', url, body=req_body)
382
Brian Waldon883cb262011-11-02 11:30:07 -0400383 # KNOWN-ISSUE 885232
384 self.assertEqual(response['status'], '409')
385 test_snapshot_while_building.tags = ['nova']