Skip to content

Commit 2c5405e

Browse files
author
Dean Troyer
committed
Fix volume qos spec list
This has been sporadically failing in functional tests due to the way the volume qos spec list command calls get_associations() for each spec. When tests run in parallel occasionally a spec from another test is present in the list returned and is deleted before the get_associations() call is made, causing a NotFound exception. We should just keep going when this occurs. * make v1 match v2 * add tests to ensure the exception is being caught and handled Closes-Bug: #1687083 Change-Id: If2d17c1deb53d293fc2c7f0c527a4e4ef6f69976
1 parent dd7da49 commit 2c5405e

5 files changed

Lines changed: 106 additions & 28 deletions

File tree

openstackclient/tests/functional/volume/v3/test_qos.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010
# License for the specific language governing permissions and limitations
1111
# under the License.
1212

13-
from openstackclient.tests.functional.volume.v2 import test_qos as v2
1413
import os
1514

15+
from openstackclient.tests.functional.volume.v2 import test_qos as v2
16+
1617

1718
class QosTests(v2.QosTests):
1819
"""Functional tests for volume qos. """

openstackclient/tests/unit/volume/v1/test_qos_specs.py

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# under the License.
1414
#
1515

16+
import copy
1617
import mock
1718
from mock import call
1819

@@ -309,13 +310,30 @@ def test_qos_disassociate_with_all_volume_types(self):
309310

310311
class TestQosList(TestQos):
311312

312-
qos_spec = volume_fakes.FakeQos.create_one_qos()
313+
qos_specs = volume_fakes.FakeQos.create_qoses(count=2)
313314
qos_association = volume_fakes.FakeQos.create_one_qos_association()
314315

316+
columns = (
317+
'ID',
318+
'Name',
319+
'Consumer',
320+
'Associations',
321+
'Properties',
322+
)
323+
data = []
324+
for q in qos_specs:
325+
data.append((
326+
q.id,
327+
q.name,
328+
q.consumer,
329+
qos_association.name,
330+
utils.format_dict(q.specs),
331+
))
332+
315333
def setUp(self):
316334
super(TestQosList, self).setUp()
317335

318-
self.qos_mock.list.return_value = [self.qos_spec]
336+
self.qos_mock.list.return_value = self.qos_specs
319337
self.qos_mock.get_associations.return_value = [self.qos_association]
320338

321339
# Get the command object to test
@@ -330,22 +348,35 @@ def test_qos_list(self):
330348
columns, data = self.cmd.take_action(parsed_args)
331349
self.qos_mock.list.assert_called_with()
332350

333-
collist = (
334-
'ID',
335-
'Name',
336-
'Consumer',
337-
'Associations',
338-
'Properties',
351+
self.assertEqual(self.columns, columns)
352+
self.assertEqual(self.data, list(data))
353+
354+
def test_qos_list_no_association(self):
355+
self.qos_mock.reset_mock()
356+
self.qos_mock.get_associations.side_effect = [
357+
[self.qos_association],
358+
exceptions.NotFound("NotFound"),
359+
]
360+
361+
arglist = []
362+
verifylist = []
363+
364+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
365+
366+
columns, data = self.cmd.take_action(parsed_args)
367+
self.qos_mock.list.assert_called_with()
368+
369+
self.assertEqual(self.columns, columns)
370+
371+
ex_data = copy.deepcopy(self.data)
372+
ex_data[1] = (
373+
self.qos_specs[1].id,
374+
self.qos_specs[1].name,
375+
self.qos_specs[1].consumer,
376+
None,
377+
utils.format_dict(self.qos_specs[1].specs),
339378
)
340-
self.assertEqual(collist, columns)
341-
datalist = ((
342-
self.qos_spec.id,
343-
self.qos_spec.name,
344-
self.qos_spec.consumer,
345-
self.qos_association.name,
346-
utils.format_dict(self.qos_spec.specs),
347-
), )
348-
self.assertEqual(datalist, tuple(data))
379+
self.assertEqual(ex_data, list(data))
349380

350381

351382
class TestQosSet(TestQos):

openstackclient/tests/unit/volume/v2/test_qos_specs.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# under the License.
1414
#
1515

16+
import copy
1617
import mock
1718
from mock import call
1819

@@ -342,6 +343,33 @@ def test_qos_list(self):
342343
self.assertEqual(self.columns, columns)
343344
self.assertEqual(self.data, list(data))
344345

346+
def test_qos_list_no_association(self):
347+
self.qos_mock.reset_mock()
348+
self.qos_mock.get_associations.side_effect = [
349+
[self.qos_association],
350+
exceptions.NotFound("NotFound"),
351+
]
352+
353+
arglist = []
354+
verifylist = []
355+
356+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
357+
358+
columns, data = self.cmd.take_action(parsed_args)
359+
self.qos_mock.list.assert_called_with()
360+
361+
self.assertEqual(self.columns, columns)
362+
363+
ex_data = copy.deepcopy(self.data)
364+
ex_data[1] = (
365+
self.qos_specs[1].id,
366+
self.qos_specs[1].name,
367+
self.qos_specs[1].consumer,
368+
None,
369+
utils.format_dict(self.qos_specs[1].specs),
370+
)
371+
self.assertEqual(ex_data, list(data))
372+
345373

346374
class TestQosSet(TestQos):
347375

openstackclient/volume/v1/qos_specs.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,20 @@ def take_action(self, parsed_args):
186186
qos_specs_list = volume_client.qos_specs.list()
187187

188188
for qos in qos_specs_list:
189-
qos_associations = volume_client.qos_specs.get_associations(qos)
190-
if qos_associations:
191-
associations = [association.name
192-
for association in qos_associations]
193-
qos._info.update({'associations': associations})
189+
try:
190+
qos_associations = volume_client.qos_specs.get_associations(
191+
qos,
192+
)
193+
if qos_associations:
194+
associations = [
195+
association.name for association in qos_associations
196+
]
197+
qos._info.update({'associations': associations})
198+
except Exception as ex:
199+
if type(ex).__name__ == 'NotFound':
200+
qos._info.update({'associations': None})
201+
else:
202+
raise
194203

195204
display_columns = (
196205
'ID', 'Name', 'Consumer', 'Associations', 'Properties')

openstackclient/volume/v2/qos_specs.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,20 @@ def take_action(self, parsed_args):
187187
qos_specs_list = volume_client.qos_specs.list()
188188

189189
for qos in qos_specs_list:
190-
qos_associations = volume_client.qos_specs.get_associations(qos)
191-
if qos_associations:
192-
associations = [association.name
193-
for association in qos_associations]
194-
qos._info.update({'associations': associations})
190+
try:
191+
qos_associations = volume_client.qos_specs.get_associations(
192+
qos,
193+
)
194+
if qos_associations:
195+
associations = [
196+
association.name for association in qos_associations
197+
]
198+
qos._info.update({'associations': associations})
199+
except Exception as ex:
200+
if type(ex).__name__ == 'NotFound':
201+
qos._info.update({'associations': None})
202+
else:
203+
raise
195204

196205
display_columns = (
197206
'ID', 'Name', 'Consumer', 'Associations', 'Properties')

0 commit comments

Comments
 (0)