Add context.target_cell() stub to DownCellFixture

This is to give the freedom to simulate down cells for each
individual cell targeted function calls.

Part of blueprint handling-down-cell

Change-Id: Ib5bfa1b6365fb78c7d3beb07c561c62ded5cb0e1
This commit is contained in:
Surya Seetharaman 2019-02-15 09:41:45 +01:00 committed by Matt Riedemann
parent 3a1b9abe39
commit 045d883772
2 changed files with 69 additions and 7 deletions

View File

@ -1951,10 +1951,10 @@ class NoopQuotaDriverFixture(fixtures.Fixture):
class DownCellFixture(fixtures.Fixture):
"""A fixture to simulate when a cell is down either due to error or timeout
This fixture will stub out the scatter_gather_cells routine used in various
cells-related API operations like listing/showing server details to return
a ``oslo_db.exception.DBError`` per cell in the results. Therefore
it is best used with a test scenario like this:
This fixture will stub out the scatter_gather_cells routine and target_cell
used in various cells-related API operations like listing/showing server
details to return a ``oslo_db.exception.DBError`` per cell in the results.
Therefore it is best used with a test scenario like this:
1. Create a server successfully.
2. Using the fixture, list/show servers. Depending on the microversion
@ -2026,11 +2026,37 @@ class DownCellFixture(fixtures.Fixture):
}
ret2 = {}
for cell in up_cell_mappings:
with context.target_cell(ctxt, cell) as cctxt:
ctxt.cell_uuid = cell.uuid
result = fn(cctxt, *args, **kwargs)
ctxt.cell_uuid = cell.uuid
cctxt = context.RequestContext.from_dict(ctxt.to_dict())
context.set_target_cell(cctxt, cell)
result = fn(cctxt, *args, **kwargs)
ret2[cell.uuid] = result
return dict(list(ret1.items()) + list(ret2.items()))
@contextmanager
def stub_target_cell(ctxt, cell_mapping):
# This is to give the freedom to simulate down cells for each
# individual cell targeted function calls.
if not self.down_cell_mappings:
# User has not passed any down cells explicitly, so all cells
# are considered as down cells.
self.down_cell_mappings = [cell_mapping]
raise db_exc.DBError()
else:
# if down_cell_mappings are passed, then check if this cell
# is down or up.
down_cell_uuids = [cell.uuid
for cell in self.down_cell_mappings]
if cell_mapping.uuid in down_cell_uuids:
# its a down cell raise the exception straight away
raise db_exc.DBError()
else:
# its an up cell, so yield its context
cctxt = context.RequestContext.from_dict(ctxt.to_dict())
context.set_target_cell(cctxt, cell_mapping)
yield cctxt
self.useFixture(fixtures.MonkeyPatch(
'nova.context.scatter_gather_cells', stub_scatter_gather_cells))
self.useFixture(fixtures.MonkeyPatch(
'nova.context.target_cell', stub_target_cell))

View File

@ -576,3 +576,39 @@ class TestDownCellFixture(test.TestCase):
self.assertIsInstance(result, objects.InstanceList)
self.assertEqual(1, len(result))
self.assertEqual(inst2.uuid, result[0].uuid)
def test_fixture_for_an_individual_down_cell_targeted_call(self):
# We have cell0 and cell1 by default in the setup. We try targeting
# both the cells. We should get a db error for the down cell and
# the correct result for the up cell.
ctxt = context.get_admin_context()
cell0 = self.cell_mappings['cell0']
cell1 = self.cell_mappings['cell1']
with context.target_cell(ctxt, cell0) as cctxt:
inst1 = fake_instance.fake_instance_obj(cctxt)
if 'id' in inst1:
delattr(inst1, 'id')
inst1.create()
with context.target_cell(ctxt, cell1) as cctxt:
inst2 = fake_instance.fake_instance_obj(cctxt)
if 'id' in inst2:
delattr(inst2, 'id')
inst2.create()
def dummy_tester(ctxt, cell_mapping, uuid):
with context.target_cell(ctxt, cell_mapping) as cctxt:
return objects.Instance.get_by_uuid(cctxt, uuid)
# Scenario A: We do not pass any down cells, fixture automatically
# assumes the targeted cell is down whether its cell0 or cell1.
with fixtures.DownCellFixture():
self.assertRaises(
db_exc.DBError, dummy_tester, ctxt, cell1, inst2.uuid)
# Scenario B: We pass cell0 as the down cell.
with fixtures.DownCellFixture([cell0]):
self.assertRaises(
db_exc.DBError, dummy_tester, ctxt, cell0, inst1.uuid)
# Scenario C: We get the correct result from the up cell
# when targeted.
result = dummy_tester(ctxt, cell1, inst2.uuid)
self.assertEqual(inst2.uuid, result.uuid)