Skip to content

Commit ee59989

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "volume functest: ensure snapshots deleted when volume delete"
2 parents c912717 + eeb614c commit ee59989

10 files changed

Lines changed: 130 additions & 129 deletions

File tree

openstackclient/tests/functional/compute/v2/common.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,12 @@ def wait_for_status(
125125
name
126126
))
127127
status = cmd_output['status']
128-
print('Waiting for {}, current status: {}'.format(
129-
expected_status,
130-
status,
131-
))
132128
if status == expected_status:
129+
print('Server {} now has status {}'.format(
130+
name, status))
133131
break
132+
print('Server {}: Waiting for {}, current status: {}'.format(
133+
name, expected_status, status))
134134
self.assertNotIn(status, failures)
135135
time.sleep(interval)
136136
total_sleep += interval

openstackclient/tests/functional/compute/v2/test_server.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
from openstackclient.tests.functional import base
1919
from openstackclient.tests.functional.compute.v2 import common
20-
from openstackclient.tests.functional.volume.v2 import test_volume
20+
from openstackclient.tests.functional.volume.v2 import common as volume_common
2121

2222

2323
class ServerTests(common.ComputeTestCase):
@@ -282,9 +282,7 @@ def test_server_reboot(self):
282282
def test_server_boot_from_volume(self):
283283
"""Test server create from volume, server delete"""
284284
# get volume status wait function
285-
volume_wait_for = test_volume.VolumeTests(
286-
methodName='wait_for',
287-
).wait_for
285+
volume_wait_for = volume_common.BaseVolumeTests.wait_for_status
288286

289287
# get image size
290288
cmd_output = json.loads(self.openstack(
@@ -391,9 +389,8 @@ def test_server_boot_from_volume(self):
391389
def test_server_boot_with_bdm_snapshot(self):
392390
"""Test server create from image with bdm snapshot, server delete"""
393391
# get volume status wait function
394-
volume_wait_for = test_volume.VolumeTests(
395-
methodName='wait_for',
396-
).wait_for
392+
volume_wait_for = volume_common.BaseVolumeTests.wait_for_status
393+
volume_wait_for_delete = volume_common.BaseVolumeTests.wait_for_delete
397394

398395
# create source empty volume
399396
empty_volume_name = uuid.uuid4().hex
@@ -419,6 +416,13 @@ def test_server_boot_with_bdm_snapshot(self):
419416
empty_snapshot_name
420417
))
421418
self.assertIsNotNone(cmd_output["id"])
419+
# Deleting volume snapshot take time, so we need to wait until the
420+
# snapshot goes. Entries registered by self.addCleanup will be called
421+
# in the reverse order, so we need to register wait_for_delete first.
422+
self.addCleanup(volume_wait_for_delete,
423+
'volume snapshot', empty_snapshot_name)
424+
self.addCleanup(self.openstack,
425+
'volume snapshot delete ' + empty_snapshot_name)
422426
self.assertEqual(
423427
empty_snapshot_name,
424428
cmd_output['name'],
@@ -489,12 +493,6 @@ def test_server_boot_with_bdm_snapshot(self):
489493
# the attached volume had been deleted
490494
pass
491495

492-
# clean up volume snapshot manually, make sure the snapshot and volume
493-
# can be deleted sequentially, self.addCleanup so fast, that cause
494-
# volume service API 400 error and the volume is left over at the end.
495-
self.openstack('volume snapshot delete ' + empty_snapshot_name)
496-
volume_wait_for('volume snapshot', empty_snapshot_name, 'disappear')
497-
498496
def test_server_create_with_none_network(self):
499497
"""Test server create with none network option."""
500498
server_name = uuid.uuid4().hex
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
import json
14+
import time
15+
16+
from openstackclient.tests.functional import base
17+
18+
19+
class BaseVolumeTests(base.TestCase):
20+
"""Base class for Volume functional tests. """
21+
22+
@classmethod
23+
def wait_for_status(cls, check_type, check_name, desired_status,
24+
wait=120, interval=5, failures=None):
25+
current_status = "notset"
26+
if failures is None:
27+
failures = ['error']
28+
total_sleep = 0
29+
while total_sleep < wait:
30+
output = json.loads(cls.openstack(
31+
check_type + ' show -f json ' + check_name))
32+
current_status = output['status']
33+
if (current_status == desired_status):
34+
print('{} {} now has status {}'
35+
.format(check_type, check_name, current_status))
36+
return
37+
print('Checking {} {} Waiting for {} current status: {}'
38+
.format(check_type, check_name,
39+
desired_status, current_status))
40+
if current_status in failures:
41+
raise Exception(
42+
'Current status {} of {} {} is one of failures {}'
43+
.format(current_status, check_type, check_name, failures))
44+
time.sleep(interval)
45+
total_sleep += interval
46+
cls.assertOutput(desired_status, current_status)
47+
48+
@classmethod
49+
def wait_for_delete(cls, check_type, check_name, wait=120, interval=5,
50+
name_field=None):
51+
total_sleep = 0
52+
name_field = name_field or 'Name'
53+
while total_sleep < wait:
54+
result = json.loads(cls.openstack(check_type + ' list -f json'))
55+
names = [x[name_field] for x in result]
56+
if check_name not in names:
57+
print('{} {} is now deleted'.format(check_type, check_name))
58+
return
59+
print('Checking {} {} Waiting for deleted'
60+
.format(check_type, check_name))
61+
time.sleep(interval)
62+
total_sleep += interval
63+
raise Exception('Timeout: {} {} was not deleted in {} seconds'
64+
.format(check_type, check_name, wait))

openstackclient/tests/functional/volume/v1/common.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212

1313
import os
1414

15-
from openstackclient.tests.functional import base
15+
from openstackclient.tests.functional.volume import base
1616

1717

18-
class BaseVolumeTests(base.TestCase):
18+
class BaseVolumeTests(base.BaseVolumeTests):
1919
"""Base class for Volume functional tests. """
2020

2121
@classmethod

openstackclient/tests/functional/volume/v1/test_snapshot.py

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
# under the License.
1212

1313
import json
14-
import time
1514
import uuid
1615

1716
from openstackclient.tests.functional.volume.v1 import common
@@ -22,16 +21,6 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
2221

2322
VOLLY = uuid.uuid4().hex
2423

25-
@classmethod
26-
def wait_for_status(cls, command, status, tries):
27-
opts = cls.get_opts(['status'])
28-
for attempt in range(tries):
29-
time.sleep(1)
30-
raw_output = cls.openstack(command + opts)
31-
if (raw_output.rstrip() == status):
32-
return
33-
cls.assertOutput(status, raw_output)
34-
3524
@classmethod
3625
def setUpClass(cls):
3726
super(VolumeSnapshotTests, cls).setUpClass()
@@ -41,12 +30,12 @@ def setUpClass(cls):
4130
'--size 1 ' +
4231
cls.VOLLY
4332
))
44-
cls.wait_for_status('volume show ' + cls.VOLLY, 'available', 6)
33+
cls.wait_for_status('volume', cls.VOLLY, 'available')
4534
cls.VOLUME_ID = cmd_output['id']
4635

4736
@classmethod
4837
def tearDownClass(cls):
49-
cls.wait_for_status('volume show ' + cls.VOLLY, 'available', 6)
38+
cls.wait_for_status('volume', cls.VOLLY, 'available')
5039
raw_output = cls.openstack('volume delete --force ' + cls.VOLLY)
5140
cls.assertOutput('', raw_output)
5241

@@ -74,14 +63,14 @@ def test_volume_snapshot__delete(self):
7463
cmd_output["display_name"],
7564
)
7665

77-
self.wait_for_status(
78-
'volume snapshot show ' + name1, 'available', 6)
79-
self.wait_for_status(
80-
'volume snapshot show ' + name2, 'available', 6)
66+
self.wait_for_status('volume snapshot', name1, 'available')
67+
self.wait_for_status('volume snapshot', name2, 'available')
8168

8269
del_output = self.openstack(
8370
'volume snapshot delete ' + name1 + ' ' + name2)
8471
self.assertOutput('', del_output)
72+
self.wait_for_delete('volume snapshot', name1)
73+
self.wait_for_delete('volume snapshot', name2)
8574

8675
def test_volume_snapshot_list(self):
8776
"""Test create, list filter"""
@@ -91,6 +80,7 @@ def test_volume_snapshot_list(self):
9180
name1 +
9281
' --volume ' + self.VOLLY
9382
))
83+
self.addCleanup(self.wait_for_delete, 'volume snapshot', name1)
9484
self.addCleanup(self.openstack, 'volume snapshot delete ' + name1)
9585
self.assertEqual(
9686
name1,
@@ -104,15 +94,15 @@ def test_volume_snapshot_list(self):
10494
1,
10595
cmd_output["size"],
10696
)
107-
self.wait_for_status(
108-
'volume snapshot show ' + name1, 'available', 6)
97+
self.wait_for_status('volume snapshot', name1, 'available')
10998

11099
name2 = uuid.uuid4().hex
111100
cmd_output = json.loads(self.openstack(
112101
'volume snapshot create -f json ' +
113102
name2 +
114103
' --volume ' + self.VOLLY
115104
))
105+
self.addCleanup(self.wait_for_delete, 'volume snapshot', name2)
116106
self.addCleanup(self.openstack, 'volume snapshot delete ' + name2)
117107
self.assertEqual(
118108
name2,
@@ -126,8 +116,7 @@ def test_volume_snapshot_list(self):
126116
1,
127117
cmd_output["size"],
128118
)
129-
self.wait_for_status(
130-
'volume snapshot show ' + name2, 'available', 6)
119+
self.wait_for_status('volume snapshot', name2, 'available')
131120

132121
# Test list --long, --status
133122
cmd_output = json.loads(self.openstack(
@@ -167,6 +156,7 @@ def test_snapshot_set(self):
167156
' --description aaaa ' +
168157
name
169158
))
159+
self.addCleanup(self.wait_for_delete, 'volume snapshot', new_name)
170160
self.addCleanup(self.openstack, 'volume snapshot delete ' + new_name)
171161
self.assertEqual(
172162
name,
@@ -180,8 +170,7 @@ def test_snapshot_set(self):
180170
'aaaa',
181171
cmd_output["display_description"],
182172
)
183-
self.wait_for_status(
184-
'volume snapshot show ' + name, 'available', 6)
173+
self.wait_for_status('volume snapshot', name, 'available')
185174

186175
# Test volume snapshot set
187176
raw_output = self.openstack(

openstackclient/tests/functional/volume/v1/test_volume.py

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
# under the License.
1212

1313
import json
14-
import time
1514
import uuid
1615

1716
from openstackclient.tests.functional.volume.v1 import common
@@ -44,8 +43,8 @@ def test_volume_create_and_delete(self):
4443
cmd_output["size"],
4544
)
4645

47-
self.wait_for("volume", name1, "available")
48-
self.wait_for("volume", name2, "available")
46+
self.wait_for_status("volume", name1, "available")
47+
self.wait_for_status("volume", name2, "available")
4948
del_output = self.openstack('volume delete ' + name1 + ' ' + name2)
5049
self.assertOutput('', del_output)
5150

@@ -62,7 +61,7 @@ def test_volume_list(self):
6261
1,
6362
cmd_output["size"],
6463
)
65-
self.wait_for("volume", name1, "available")
64+
self.wait_for_status("volume", name1, "available")
6665

6766
name2 = uuid.uuid4().hex
6867
cmd_output = json.loads(self.openstack(
@@ -75,7 +74,7 @@ def test_volume_list(self):
7574
2,
7675
cmd_output["size"],
7776
)
78-
self.wait_for("volume", name2, "available")
77+
self.wait_for_status("volume", name2, "available")
7978

8079
# Test list
8180
cmd_output = json.loads(self.openstack(
@@ -131,7 +130,7 @@ def test_volume_set_and_unset(self):
131130
'false',
132131
cmd_output["bootable"],
133132
)
134-
self.wait_for("volume", name, "available")
133+
self.wait_for_status("volume", name, "available")
135134

136135
# Test volume set
137136
new_name = uuid.uuid4().hex
@@ -208,7 +207,7 @@ def test_volume_create_and_list_and_show_backward_compatibility(self):
208207
self.assertNotIn('name', json_output)
209208
self.addCleanup(self.openstack, 'volume delete ' + volume_id)
210209

211-
self.wait_for("volume", name1, "available")
210+
self.wait_for_status("volume", name1, "available")
212211

213212
json_output = json.loads(self.openstack(
214213
'volume list -f json ' +
@@ -233,20 +232,3 @@ def test_volume_create_and_list_and_show_backward_compatibility(self):
233232
self.assertEqual(name1, json_output['display_name'])
234233
self.assertIn('id', json_output)
235234
self.assertNotIn('name', json_output)
236-
237-
def wait_for(self, check_type, check_name, desired_status, wait=120,
238-
interval=5, failures=['ERROR']):
239-
status = "notset"
240-
total_sleep = 0
241-
opts = self.get_opts(['status'])
242-
while total_sleep < wait:
243-
status = self.openstack(check_type + ' show ' + check_name + opts)
244-
status = status.rstrip()
245-
print('Checking {} {} Waiting for {} current status: {}'
246-
.format(check_type, check_name, desired_status, status))
247-
if status == desired_status:
248-
break
249-
self.assertNotIn(status, failures)
250-
time.sleep(interval)
251-
total_sleep += interval
252-
self.assertEqual(desired_status, status)

openstackclient/tests/functional/volume/v2/common.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212

1313
import os
1414

15-
from openstackclient.tests.functional import base
15+
from openstackclient.tests.functional.volume import base
1616

1717

18-
class BaseVolumeTests(base.TestCase):
18+
class BaseVolumeTests(base.BaseVolumeTests):
1919
"""Base class for Volume functional tests. """
2020

2121
@classmethod

0 commit comments

Comments
 (0)