-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fill fault from all nova cells in GET servers/detail #125
base: stable/queens-m3
Are you sure you want to change the base?
Changes from 5 commits
ff14e3d
67184ab
b541095
058fba6
53e9bf4
dd1c37c
6670706
3998251
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
# License for the specific language governing permissions and limitations | ||
# under the License. | ||
|
||
from contextlib import contextmanager | ||
import datetime | ||
|
||
import mock | ||
|
@@ -1869,13 +1870,22 @@ def test_with_fault(self, mock_get_all, mock_fault_get): | |
mock_fault_get.assert_called_once_with(self.context, | ||
[x['uuid'] for x in fake_insts]) | ||
|
||
@mock.patch('nova.objects.InstanceMappingList.get_by_instance_uuids') | ||
@mock.patch.object(db, 'instance_fault_get_by_instance_uuids') | ||
def test_fill_faults(self, mock_fault_get): | ||
def test_fill_faults(self, mock_fault_get, mock_get_inst_map_list): | ||
inst1 = objects.Instance(uuid=uuids.db_fault_1) | ||
inst2 = objects.Instance(uuid=uuids.db_fault_2) | ||
insts = [inst1, inst2] | ||
for inst in insts: | ||
inst.obj_reset_changes() | ||
|
||
mock_get_inst_map_list.return_value = [ | ||
mock.Mock(cell_mapping=None, | ||
instance_uuid=uuids.db_fault_1), | ||
mock.Mock(cell_mapping=None, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both your instances have the same cell here. If we want to upstream this - and we should - we need a proper test-case. Best thing is to have a test-case that can be run without your changes, but fails, so we can convince upstream that there's a bug. It should then work with your changes obviously ;) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. Improved test to cover different cells. |
||
instance_uuid=uuids.db_fault_2) | ||
] | ||
|
||
db_faults = { | ||
'uuid1': [{'id': 123, | ||
'instance_uuid': uuids.db_fault_1, | ||
|
@@ -1902,10 +1912,83 @@ def test_fill_faults(self, mock_fault_get): | |
for inst in inst_list: | ||
self.assertEqual(set(), inst.obj_what_changed()) | ||
|
||
mock_fault_get.assert_called_once_with(self.context, | ||
mock_fault_get.assert_called_once_with(mock.ANY, | ||
[x.uuid for x in insts], | ||
latest=True) | ||
|
||
@mock.patch('nova.context.target_cell') | ||
@mock.patch('nova.objects.InstanceMappingList.get_by_instance_uuids') | ||
@mock.patch.object(db, 'instance_fault_get_by_instance_uuids') | ||
def test_fill_faults_multicell(self, | ||
mock_fault_get, | ||
mock_get_inst_map_list, | ||
mock_ctxt_target_cell): | ||
# Prepare list with 2 instances | ||
inst_list = objects.InstanceList() | ||
inst_list._context = self.context | ||
inst_list.objects = [ | ||
objects.Instance(uuid=uuids.inst_1), | ||
objects.Instance(uuid=uuids.inst_2) | ||
] | ||
for inst in inst_list.objects: | ||
inst.obj_reset_changes() | ||
|
||
# Define different cell mappings for the 2 instances | ||
im1 = mock.Mock(instance_uuid=uuids.inst_1, | ||
cell_mapping=mock.Mock( | ||
database_connection=self.context.db_connection)) | ||
im2 = mock.Mock(instance_uuid=uuids.inst_2) | ||
mock_get_inst_map_list.return_value = [im1, im2] | ||
|
||
# Define faults for the instances in different cell DBs (mocked) | ||
def _fake_db_faults(instance_uuid): | ||
return { | ||
instance_uuid: [{ | ||
'id': 123, | ||
'instance_uuid': instance_uuid, | ||
'code': 456, | ||
'message': 'Fake message %s' % instance_uuid, | ||
'details': 'No details', | ||
'host': 'foo', | ||
'deleted': False, | ||
'deleted_at': None, | ||
'updated_at': None, | ||
'created_at': None | ||
}] | ||
} | ||
|
||
db_1_faults = _fake_db_faults(uuids.inst_1) | ||
db_2_faults = _fake_db_faults(uuids.inst_2) | ||
cell_faults = [ | ||
(im1.cell_mapping, db_1_faults), | ||
(im2.cell_mapping, db_2_faults) | ||
] | ||
|
||
def _mock_cell_fault_get(context, instance_uuids, latest=False): | ||
for cf in cell_faults: | ||
if context.db_connection == cf[0].database_connection: | ||
return cf[1] | ||
return None | ||
mock_fault_get.side_effect = _mock_cell_fault_get | ||
|
||
@contextmanager | ||
def _mock_ctxt_target_cell(context, cell_mapping): | ||
yield mock.Mock( | ||
db_connection= | ||
(cell_mapping.database_connection | ||
if cell_mapping | ||
and hasattr(cell_mapping, 'database_connection') | ||
else None)) | ||
mock_ctxt_target_cell.side_effect = _mock_ctxt_target_cell | ||
|
||
inst_list.fill_faults() | ||
# Verify multicell fill_faults by comparing combined list of faults | ||
# from different cell DBs to the list of instance faults as filled | ||
self.assertEqual([db_1_faults[uuids.inst_1][0]['message'], | ||
db_2_faults[uuids.inst_2][0]['message']], | ||
[getattr(inst.fault, 'message', None) | ||
for inst in inst_list]) | ||
|
||
@mock.patch('nova.objects.instance.Instance.obj_make_compatible') | ||
def test_get_by_security_group(self, mock_compat): | ||
fake_secgroup = dict(test_security_group.fake_secgroup) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I understand this correctly:
cell_id
can beNone
andim.cell_mapping
can beNone
, too? Should we have anif cell_id is None: continue
in the for-loop?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. PR updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're missing a test for this. You updated the tests, so the cell-mapping is there, but nothing failed before, so we're missing a test.