'Common code for testing save() for cells/non-cells.'

@mock.patch.object(notifications, 'send_update')
@mock.patch.object(cells_rpcapi, 'CellsAPI')
@mock.patch.object(db, 'instance_info_cache_update')
@mock.patch.object(db, 'instance_update_and_get_original')
@mock.patch.object(db, 'instance_get_by_uuid')
def _save_test_helper(self, cell_type, save_kwargs, mock_db_instance_get_by_uuid, mock_db_instance_update_and_get_original, mock_db_instance_info_cache_update, mock_cells_rpcapi_CellsAPI, mock_notifications_send_update):

    if cell_type:
        self.flags(enable=True, cell_type=cell_type, group='cells')
    else:
        self.flags(enable=False, group='cells')
    old_ref = dict(self.fake_instance, host='oldhost', user_data='old', vm_state='old', task_state='old')
    fake_uuid = old_ref['uuid']
    expected_updates = dict(vm_state='meow', task_state='wuff', user_data='new')
    new_ref = dict(old_ref, host='newhost', **expected_updates)
    exp_vm_state = save_kwargs.get('expected_vm_state')
    exp_task_state = save_kwargs.get('expected_task_state')
    admin_reset = save_kwargs.get('admin_state_reset', False)
    if exp_vm_state:
        expected_updates['expected_vm_state'] = exp_vm_state
    if exp_task_state:
        if ((exp_task_state == 'image_snapshot') and ('instance_version' in save_kwargs) and (save_kwargs['instance_version'] == '1.9')):
            expected_updates['expected_task_state'] = ['image_snapshot', 'image_snapshot_pending']
        else:
            expected_updates['expected_task_state'] = exp_task_state
    mock_db_instance_get_by_uuid.return_value = old_ref
    mock_db_instance_update_and_get_original.return_value = (old_ref, new_ref)
    inst = objects.Instance.get_by_uuid(self.context, old_ref['uuid'])
    if ('instance_version' in save_kwargs):
        inst.VERSION = save_kwargs.pop('instance_version')
    self.assertEqual('old', inst.task_state)
    self.assertEqual('old', inst.vm_state)
    self.assertEqual('old', inst.user_data)
    inst.vm_state = 'meow'
    inst.task_state = 'wuff'
    inst.user_data = 'new'
    save_kwargs.pop('context', None)
    inst.save(**save_kwargs)
    self.assertEqual('newhost', inst.host)
    self.assertEqual('meow', inst.vm_state)
    self.assertEqual('wuff', inst.task_state)
    self.assertEqual('new', inst.user_data)
    self.assertEqual(set([]), (inst.obj_what_changed() - set(['flavor'])))
    mock_db_instance_get_by_uuid.assert_called_once_with(self.context, fake_uuid, columns_to_join=['info_cache', 'security_groups'])
    mock_db_instance_update_and_get_original.assert_called_once_with(self.context, fake_uuid, expected_updates, columns_to_join=['info_cache', 'security_groups', 'system_metadata', 'extra', 'extra.flavor'])
    if (cell_type == 'api'):
        mock_cells_rpcapi_CellsAPI.return_value.instance_update_from_api.assert_called_once_with(self.context, test.MatchType(objects.Instance), exp_vm_state, exp_task_state, admin_reset)
    elif (cell_type == 'compute'):
        mock_cells_rpcapi_CellsAPI.return_value.instance_update_at_top.assert_called_once_with(self.context, mock.ANY)
    mock_notifications_send_update.assert_called_with(self.context, mock.ANY, mock.ANY)
