Fix TypeError in nova-manage cell_v2 list_cells

Cell mappings don't require a name, so when listing
cells, if any mappings don't have a name, the sorted
function will fail with a TypeError since you can't compare
None to a string.

This fixes the issue by using the empty string if the cell
mapping name is None.

Change-Id: I4fc9d8d1a96f1ec722c2c92dead3f5c4c94d4382
Closes-Bug: #1790695
This commit is contained in:
Matt Riedemann 2018-09-04 18:28:21 -04:00
parent 5c6b22559d
commit a4f1274f40
2 changed files with 20 additions and 11 deletions

View File

@ -1488,8 +1488,10 @@ class CellV2Commands(object):
_('Database Connection'), _('Disabled')]
t = prettytable.PrettyTable(field_names)
for cell in sorted(cell_mappings, key=lambda _cell: _cell.name):
fields = [cell.name, cell.uuid]
for cell in sorted(cell_mappings,
# CellMapping.name is optional
key=lambda _cell: _cell.name or ''):
fields = [cell.name or '', cell.uuid]
if verbose:
fields.extend([cell.transport_url, cell.database_connection])
else:

View File

@ -1859,7 +1859,7 @@ class CellV2CommandsTestCase(test.NoDBTestCase):
self.assertEqual(kwargs['name'], cell1.name)
self.assertIs(cell1.disabled, True)
def test_list_cells_no_cells_verbose_false(self):
def test_list_cells_verbose_false(self):
ctxt = context.RequestContext()
cell_mapping0 = objects.CellMapping(
context=ctxt, uuid=uuidsentinel.map0,
@ -1903,19 +1903,26 @@ class CellV2CommandsTestCase(test.NoDBTestCase):
database_connection='fake:///dbdal', transport_url='fake:///mqdal',
name='dallas')
cell_mapping2.create()
no_name = objects.CellMapping(
context=ctxt, uuid=uuidsentinel.none,
database_connection='fake:///dbnone',
transport_url='fake:///mqnone')
no_name.create()
self.assertEqual(0, self.commands.list_cells(verbose=True))
output = self.output.getvalue().strip()
self.assertEqual('''\
+--------+--------------------------------------+---------------+---------------------+----------+
| Name | UUID | Transport URL | Database Connection | Disabled |
+--------+--------------------------------------+---------------+---------------------+----------+
| cell0 | %(uuid_map0)s | none:/// | fake:///db0 | False |
| dallas | %(uuid_map2)s | fake:///mqdal | fake:///dbdal | False |
| london | %(uuid_map1)s | fake:///mqlon | fake:///dblon | True |
+--------+--------------------------------------+---------------+---------------------+----------+''' % # noqa
+--------+--------------------------------------+----------------+---------------------+----------+
| Name | UUID | Transport URL | Database Connection | Disabled |
+--------+--------------------------------------+----------------+---------------------+----------+
| | %(uuid_none)s | fake:///mqnone | fake:///dbnone | False |
| cell0 | %(uuid_map0)s | none:/// | fake:///db0 | False |
| dallas | %(uuid_map2)s | fake:///mqdal | fake:///dbdal | False |
| london | %(uuid_map1)s | fake:///mqlon | fake:///dblon | True |
+--------+--------------------------------------+----------------+---------------------+----------+''' % # noqa
{"uuid_map0": uuidsentinel.map0,
"uuid_map1": uuidsentinel.map1,
"uuid_map2": uuidsentinel.map2},
"uuid_map2": uuidsentinel.map2,
"uuid_none": uuidsentinel.none},
output)
def test_delete_cell_not_found(self):