class VolumeGroupsTests(unittest.TestCase):
    def setUp(self):
        objstore_loc = config.get_object_store() + "_ginger"
        self._objstore = ObjectStore(objstore_loc)
        self.task_model = TaskModel(objstore=self._objstore)

    def test_get_vg_list(self):
        vgs = vol_group.VolumeGroupsModel(objstore=self._objstore)
        vgs_list = vgs.get_list()
        self.assertGreaterEqual(len(vgs_list), 0)

    def test_create_vg_missing_name(self):
        vgs = vol_group.VolumeGroupsModel(objstore=self._objstore)
        pvpaths = ["/dev/sdb1"]
        params = {"pv_paths": pvpaths}
        self.assertRaises(MissingParameter, vgs.create, params)

    def test_create_vg_missing_pvpaths(self):
        vgs = vol_group.VolumeGroupsModel(objstore=self._objstore)
        vgname = "testvg"
        params = {"vg_name": vgname}
        self.assertRaises(MissingParameter, vgs.create, params)

    @mock.patch("wok.plugins.ginger.models.utils._create_vg", autospec=True)
    def test_create_vg(self, mock_create_vg):
        vgs = vol_group.VolumeGroupsModel(objstore=self._objstore)
        vgname = "testvg"
        pvpaths = ["/dev/sdb1"]
        params = {"vg_name": vgname, "pv_paths": pvpaths}
        task_obj = vgs.create(params)
        self.task_model.wait(task_obj.get("id"))
        mock_create_vg.assert_called_with(vgname, pvpaths)

    @mock.patch("wok.plugins.ginger.models.utils._extend_vg", autospec=True)
    def test_extend_vg(self, mock_extend_vg):
        vg = vol_group.VolumeGroupModel(objstore=self._objstore)
        vgname = "testvg"
        pvpaths = ["/dev/sdb2"]
        vg.extend(vgname, pvpaths)
        mock_extend_vg.assert_called_with(vgname, pvpaths)

    @mock.patch("wok.plugins.ginger.models.utils._reduce_vg", autospec=True)
    def test_reduce_vg(self, mock_reduce_vg):
        vg = vol_group.VolumeGroupModel(objstore=self._objstore)
        vgname = "testvg"
        pvpaths = ["/dev/sdb2"]
        vg.reduce(vgname, pvpaths)
        mock_reduce_vg.assert_called_with(vgname, pvpaths)

    @mock.patch("wok.plugins.ginger.models.utils._remove_vg", autospec=True)
    def test_delete_vg(self, mock_delete_vg):
        vg = vol_group.VolumeGroupModel(objstore=self._objstore)
        vgname = "testvg"
        vg.delete(vgname)
        mock_delete_vg.assert_called_with(vgname)
class FirmwareProgressTests(unittest.TestCase):
    def setUp(self):
        objstore_loc = config.get_object_store() + '_ginger'
        self._objstore = ObjectStore(objstore_loc)
        self.task = TaskModel(objstore=self._objstore)

    def test_fwprogress_without_update_flash(self):
        fwprogress = FirmwareProgressModel(objstore=self._objstore)
        task_info = fwprogress.lookup()
        self.task.wait(task_info['id'])
        task_info = self.task.lookup(task_info['id'])

        self.assertEquals('finished', task_info['status'])
        self.assertIn('Error', task_info['message'])
        self.assertEquals('/plugins/ginger/fwprogress',
                          task_info['target_uri'])
Exemple #3
0
class LogicalVolumesTests(unittest.TestCase):
    def setUp(self):
        objstore_loc = config.get_object_store() + '_ginger'
        self._objstore = ObjectStore(objstore_loc)
        self.task_model = TaskModel(objstore=self._objstore)

    def test_get_lv_list(self):
        lvs = log_volume.LogicalVolumesModel(objstore=self._objstore)
        lvs_list = lvs.get_list()
        self.assertGreaterEqual(len(lvs_list), 0)

    def test_create_lv_missing_vgname(self):
        lvs = log_volume.LogicalVolumesModel(objstore=self._objstore)
        size = ['10M']
        params = {'size': size}
        self.assertRaises(MissingParameter, lvs.create, params)

    def test_create_lv_missing_size(self):
        lvs = log_volume.LogicalVolumesModel(objstore=self._objstore)
        vgname = 'testvg'
        params = {'vg_name': vgname}
        self.assertRaises(MissingParameter, lvs.create, params)

    @mock.patch('wok.plugins.ginger.model.utils._create_lv', autospec=True)
    def test_create_lv(self, mock_create_lv):
        lvs = log_volume.LogicalVolumesModel(objstore=self._objstore)
        vgname = 'testvg'
        size = '10M'
        params = {'vg_name': vgname, 'size': size}
        task_obj = lvs.create(params)
        self.task_model.wait(task_obj.get('id'))
        mock_create_lv.assert_called_with(vgname, size)

    @mock.patch('wok.plugins.ginger.model.utils._remove_lv',
                autospec=True)
    def test_delete_lv(self, mock_delete_lv):
        lv = log_volume.LogicalVolumeModel(objstore=self._objstore)
        lvname = '/dev/testvg/lvol0'
        lv.delete(lvname)
        mock_delete_lv.assert_called_with(lvname)
Exemple #4
0
class LogicalVolumesTests(unittest.TestCase):
    def setUp(self):
        objstore_loc = config.get_object_store() + '_ginger'
        self._objstore = ObjectStore(objstore_loc)
        self.task_model = TaskModel(objstore=self._objstore)

    def test_get_lv_list(self):
        lvs = log_volume.LogicalVolumesModel(objstore=self._objstore)
        lvs_list = lvs.get_list()
        self.assertGreaterEqual(len(lvs_list), 0)

    def test_create_lv_missing_vgname(self):
        lvs = log_volume.LogicalVolumesModel(objstore=self._objstore)
        size = ['10M']
        params = {'size': size}
        self.assertRaises(MissingParameter, lvs.create, params)

    def test_create_lv_missing_size(self):
        lvs = log_volume.LogicalVolumesModel(objstore=self._objstore)
        vgname = 'testvg'
        params = {'vg_name': vgname}
        self.assertRaises(MissingParameter, lvs.create, params)

    @mock.patch('wok.plugins.ginger.model.utils._create_lv', autospec=True)
    def test_create_lv(self, mock_create_lv):
        lvs = log_volume.LogicalVolumesModel(objstore=self._objstore)
        vgname = 'testvg'
        size = '10M'
        params = {'vg_name': vgname, 'size': size}
        task_obj = lvs.create(params)
        self.task_model.wait(task_obj.get('id'))
        mock_create_lv.assert_called_with(vgname, size)

    @mock.patch('wok.plugins.ginger.model.utils._remove_lv', autospec=True)
    def test_delete_lv(self, mock_delete_lv):
        lv = log_volume.LogicalVolumeModel(objstore=self._objstore)
        lvname = '/dev/testvg/lvol0'
        lv.delete(lvname)
        mock_delete_lv.assert_called_with(lvname)
Exemple #5
0
class VolumeGroupsTests(unittest.TestCase):

    def setUp(self):
        objstore_loc = config.get_object_store() + '_ginger'
        self._objstore = ObjectStore(objstore_loc)
        self.task_model = TaskModel(objstore=self._objstore)

    def test_get_vg_list(self):
        vgs = vol_group.VolumeGroupsModel(objstore=self._objstore)
        vgs_list = vgs.get_list()
        self.assertGreaterEqual(len(vgs_list), 0)

    def test_create_vg_missing_name(self):
        vgs = vol_group.VolumeGroupsModel(objstore=self._objstore)
        pvpaths = ['/dev/sdb1']
        params = {'pv_paths': pvpaths}
        self.assertRaises(MissingParameter, vgs.create, params)

    def test_create_vg_missing_pvpaths(self):
        vgs = vol_group.VolumeGroupsModel(objstore=self._objstore)
        vgname = 'testvg'
        params = {'vg_name': vgname}
        self.assertRaises(MissingParameter, vgs.create, params)

    @mock.patch('wok.plugins.ginger.model.utils._create_vg', autospec=True)
    def test_create_vg(self, mock_create_vg):
        vgs = vol_group.VolumeGroupsModel(objstore=self._objstore)
        vgname = 'testvg'
        pvpaths = ['/dev/sdb1']
        params = {'vg_name': vgname, 'pv_paths': pvpaths}
        task_obj = vgs.create(params)
        self.task_model.wait(task_obj.get('id'))
        mock_create_vg.assert_called_with(vgname, pvpaths)

    @mock.patch('wok.plugins.ginger.model.utils._extend_vg', autospec=True)
    def test_extend_vg(self, mock_extend_vg):
        vg = vol_group.VolumeGroupModel(objstore=self._objstore)
        vgname = 'testvg'
        pvpaths = ['/dev/sdb2']
        vg.extend(vgname, pvpaths)
        mock_extend_vg.assert_called_with(vgname, pvpaths)

    @mock.patch('wok.plugins.ginger.model.utils._reduce_vg', autospec=True)
    def test_reduce_vg(self, mock_reduce_vg):
        vg = vol_group.VolumeGroupModel(objstore=self._objstore)
        vgname = 'testvg'
        pvpaths = ['/dev/sdb2']
        vg.reduce(vgname, pvpaths)
        mock_reduce_vg.assert_called_with(vgname, pvpaths)

    @mock.patch('wok.plugins.ginger.model.utils._remove_vg',
                autospec=True)
    @mock.patch('wok.plugins.ginger.model.utils.get_lvm_version')
    @mock.patch('wok.plugins.ginger.model.vol_group.VolumeGroupModel.lookup')
    def test_delete_vg(self, mock_vg_lookup, mock_lvm_version, mock_delete_vg):
        mock_lvm_version.return_value = "2.02.98"
        mock_vg_lookup.return_value = {'vgName': 'testvg', 'Cur LV': 0}
        vg = vol_group.VolumeGroupModel(objstore=self._objstore)
        vgname = 'testvg'
        vg.delete(vgname)
        mock_delete_vg.assert_called_with(vgname)

    def test_parse_lvm_version(self):
        lvm_version_input = "     2.02.98(2) (2012-10-15)"
        lvm_version = utils._parse_lvm_version(lvm_version_input)
        if lvm_version != "2.02.98":
            self.fail()

    def test_parse_lvm_version_exception(self):
        lvm_version_input = "     wrong version string"
        self.assertRaises(
            OperationFailed,
            utils._parse_lvm_version,
            lvm_version_input)
class InterfacesTests(unittest.TestCase):

    def setUp(self):
        objstore_loc = config.get_object_store() + '_ginger'
        self._objstore = ObjectStore(objstore_loc)
        self.task = TaskModel(objstore=self._objstore)

    @mock.patch('wok.plugins.gingerbase.netinfo.os')
    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_type')
    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.run_command')
    def test_activate(self, mock_run_command, mock_get_interface_type,
                      mock_os):
        mock_run_command.return_value = ["", "", 0]
        mock_os.path.isfile.return_value = True
        mock_get_interface_type.return_value = "nic"
        interface = "test_eth0"
        cmd = ['ip', 'link', 'set', '%s' % interface, 'up']
        InterfaceModel(objstore=self._objstore).activate(interface)
        mock_run_command.assert_called_once_with(cmd)

    @mock.patch('wok.plugins.gingerbase.netinfo.os')
    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_type')
    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.run_command')
    def test_activate_no_config_file(self, mock_run_command,
                                     mock_get_interface_type, mock_os):
        mock_run_command.return_value = ["", "", 0]
        mock_os.path.isfile.return_value = False
        mock_get_interface_type.return_value = "nic"
        interface = "test_eth0"
        calls = [(['ip', 'link', 'set', '%s' % interface, 'up'],),
                 (['ifup', '%s' % interface],)]
        InterfaceModel(objstore=self._objstore).activate(interface)
        for i in range(0, 1):
            x, y = mock_run_command.call_args_list[i]
            assert x == calls[i]
        assert mock_run_command.call_count == 1

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_type')
    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.run_command')
    def test_activate_fail(self, mock_run_command, mock_get_interface_type):
        mock_run_command.return_value = ["", "Unable to activate", 4]
        mock_get_interface_type.return_value = "nic"
        interface = "test_eth0"
        cmd = ['ip', 'link', 'set', '%s' % interface, 'up']
        self.assertRaises(OperationFailed,
                          InterfaceModel(objstore=self._objstore).activate,
                          interface)
        mock_run_command.assert_called_once_with(cmd)

    @mock.patch('wok.plugins.gingerbase.netinfo.os')
    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_type')
    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.run_command')
    def test_deactivate(self, mock_run_command, mock_get_interface_type,
                        mock_os):
        mock_run_command.return_value = ["", "", 0]
        mock_os.path.isfile.return_value = True
        mock_get_interface_type.return_value = "nic"
        interface = "test_eth0"
        cmd = ['ip', 'link', 'set', '%s' % interface, 'down']
        InterfaceModel(objstore=self._objstore).deactivate(interface)
        mock_run_command.assert_called_once_with(cmd)

    @mock.patch('wok.plugins.gingerbase.netinfo.os')
    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_type')
    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.run_command')
    def test_deactivate_no_config_file(self, mock_run_command,
                                       mock_get_interface_type, mock_os):
        mock_run_command.return_value = ["", "", 0]
        mock_os.path.isfile.return_value = False
        mock_get_interface_type.return_value = "nic"
        interface = "test_eth0"
        calls = [(['ip', 'link', 'set', '%s' % interface, 'down'],),
                 (['ifdown', '%s' % interface],)]
        InterfaceModel(objstore=self._objstore).deactivate(interface)
        for i in range(0, 1):
            x, y = mock_run_command.call_args_list[i]
            assert x == calls[i]
        assert mock_run_command.call_count == 1

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_type')
    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.run_command')
    def test_deactivate_fail(self, mock_run_command, mock_get_interface_type):
        mock_run_command.return_value = ["", "Unable to deactivate", 4]
        mock_get_interface_type.return_value = "nic"
        interface = "test_eth0"
        cmd = ['ip', 'link', 'set', '%s' % interface, 'down']
        self.assertRaises(OperationFailed,
                          InterfaceModel(objstore=self._objstore).deactivate,
                          interface)
        mock_run_command.assert_called_once_with(cmd)

    @mock.patch('os.readlink')
    def test_netinfo_interface_module_lookup_success(self, mock_readlink):
        mock_readlink.return_value = '../../../../module/dummy_net_module'

        module = netinfo.get_interface_kernel_module('dummy_iface')
        mock_readlink.assert_called_once_with(
            '/sys/class/net/dummy_iface/device/driver/module')

        self.assertEqual(module, 'dummy_net_module')

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('ethtool.get_devices')
    @mock.patch('ethtool.get_ipaddr')
    @mock.patch('ethtool.get_netmask')
    @mock.patch('wok.plugins.gingerbase.netinfo.macaddr')
    def test_netinfo_get_interface_info(self, mock_macaddr, mock_netmask,
                                        mock_ipaddr, mock_getdevs,
                                        mock_get_module):
        mock_get_module.return_value = 'dummy_net_module'
        mock_getdevs.return_value = ['dev1', 'dummy_iface', 'dev2']
        mock_ipaddr.return_value = '99.99.99.99'
        mock_netmask.return_value = '255.255.255.0'
        mock_macaddr.return_value = 'aa:bb:cc:dd:ee:ff'

        iface_info = netinfo.get_interface_info('dummy_iface')

        mock_macaddr.assert_called_once_with('dummy_iface')
        mock_netmask.assert_called_once_with('dummy_iface')
        mock_ipaddr.assert_called_once_with('dummy_iface')
        mock_getdevs.assert_called_once_with()
        mock_get_module.assert_called_once_with('dummy_iface')

        self.assertEqual(iface_info.get('device'), 'dummy_iface')
        self.assertEqual(iface_info.get('type'), 'unknown')
        self.assertEqual(iface_info.get('status'), 'down')
        self.assertEqual(iface_info.get('ipaddr'), '99.99.99.99')
        self.assertEqual(iface_info.get('netmask'), '255.255.255.0')
        self.assertEqual(iface_info.get('macaddr'), 'aa:bb:cc:dd:ee:ff')
        self.assertEqual(iface_info.get('module'), 'dummy_net_module')

    @mock.patch('ethtool.get_devices')
    @mock.patch('wok.plugins.gingerbase.netinfo.is_rdma_enabled')
    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_info')
    def test_interface_lookup(self, mock_iface_info, mock_rdma_enabled,
                              mock_getdevs):
        iface_info_return = {
            'device': 'dummy_iface', 'type': 'unknown', 'status': 'down',
            'ipaddr': '99.99.99.99', 'netmask': '255.255.255.0',
            'macaddr': 'aa:bb:cc:dd:ee:ff', 'module': 'dummy_net_module'
        }
        mock_iface_info.return_value = iface_info_return
        mock_rdma_enabled.return_value = True
        mock_getdevs.return_value = ['dev1', 'dummy_iface', 'dev2']

        iface_model = InterfaceModel(objstore=self._objstore)
        iface_info = iface_model.lookup('dummy_iface')
        mock_iface_info.assert_called_once_with('dummy_iface')
        mock_rdma_enabled.assert_called_once_with('dummy_iface')
        mock_getdevs.called_once_with()

        self.assertEqual(iface_info.get('device'), 'dummy_iface')
        self.assertEqual(iface_info.get('type'), 'unknown')
        self.assertEqual(iface_info.get('status'), 'down')
        self.assertEqual(iface_info.get('ipaddr'), '99.99.99.99')
        self.assertEqual(iface_info.get('netmask'), '255.255.255.0')
        self.assertEqual(iface_info.get('macaddr'), 'aa:bb:cc:dd:ee:ff')
        self.assertEqual(iface_info.get('module'), 'dummy_net_module')
        self.assertTrue(iface_info.get('rdma_enabled'))

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    def test_invalid_module_enable_sriov_failure(self, mock_get_module):
        mock_get_module.return_value = 'unknown'

        expected_error_msg = "GINNET0076E"
        with self.assertRaisesRegexp(InvalidOperation, expected_error_msg):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('any_iface_name', {'num_vfs': 4})

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_no_args_failure(self, mock_get_max_VF,
                                        mock_get_module):

        mock_get_max_VF.return_value = '1'
        mock_get_module.return_value = 'mlx5_core'

        expected_error_msg = "GINNET0077E"
        with self.assertRaisesRegexp(InvalidParameter, expected_error_msg):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('any_iface_name', None)

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_argument_failure(self, mock_get_max_VF,
                                         mock_get_module):

        mock_get_max_VF.return_value = '1'
        mock_get_module.return_value = 'mlx5_core'

        expected_error_msg = "GINNET0079E"
        with self.assertRaisesRegexp(InvalidParameter, expected_error_msg):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('any_iface_name', 'not_an_int')

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_no_system_files_failure(self, mock_get_max_VF,
                                                mock_isfile,
                                                mock_get_module):
        mock_get_max_VF.return_value = '8'
        mock_get_module.return_value = 'mlx5_core'

        call_file1_not_exist = \
            '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        call_file2_not_exist = \
            '/sys/class/net/%s/device/mlx5_num_vfs' % 'iface1'

        mock_isfile.side_effect = [False, False]

        mock_isfile_calls = [
            call(call_file1_not_exist),
            call(call_file2_not_exist)
        ]

        expected_error_msg = "GINNET0078E"
        with self.assertRaisesRegexp(OperationFailed, expected_error_msg):
            iface_model = InterfaceModel(objstore=self._objstore)
            task_obj = iface_model.enable_sriov('iface1', 4)
            self.task.wait(task_obj['id'])

            mock_isfile.assert_has_calls(mock_isfile_calls)

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    def test_mlx5_sriov_not_enabled_in_FW(self, mock_isfile, mock_get_module):
        mock_get_module.return_value = 'mlx5_core'

        file1 = '/sys/class/net/%s/device/sriov_totalvfs' % 'iface1'
        mock_isfile.return_value = False

        with self.assertRaisesRegexp(OperationFailed, 'GINNET0082E'):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('iface1', 4)
            mock_isfile.assert_called_once_with(file1)

    @mock.patch('os.path.isfile')
    def test_mlx5_sriov_get_maxVF_value(self, mock_isfile):
        file1 = '/sys/class/net/%s/device/sriov_totalvfs' % 'iface1'
        mock_isfile.return_value = True

        open_ = mock_open(read_data='8\n')

        with patch.object(builtins, 'open', open_):
            iface_model = InterfaceModel(objstore=self._objstore)
            max_vf_str = iface_model._mlx5_SRIOV_get_max_VF('iface1')
            mock_isfile.assert_called_once_with(file1)
            self.assertEqual(max_vf_str, '8')

        self.assertEqual(open_.call_args_list, [call(file1, 'r')])

    @mock.patch('os.path.isfile')
    def test_mlx5_sriov_get_currentVF_value(self, mock_isfile):
        file1 = '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        mock_isfile.return_value = True

        open_ = mock_open(read_data='5\n')

        with patch.object(builtins, 'open', open_):
            iface_model = InterfaceModel(objstore=self._objstore)
            curr_vf_str = iface_model._mlx5_SRIOV_get_current_VFs('iface1')
            mock_isfile.assert_called_once_with(file1)
            self.assertEqual(curr_vf_str, '5')

        self.assertEqual(open_.call_args_list, [call(file1, 'r')])

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_fails_if_VF_greater_max(self, mock_get_max_VF,
                                                mock_isfile, mock_get_module):

        mock_get_max_VF.return_value = '8'
        mock_get_module.return_value = 'mlx5_core'

        file1 = '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        mock_isfile.return_value = True

        with self.assertRaisesRegexp(InvalidParameter, 'GINNET0083E'):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('iface1', 16)
            mock_isfile.assert_called_once_with(file1)

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_current_VFs')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_fails_if_VF_equal_to_current(
        self, mock_get_max_VF, mock_get_current_VF,
        mock_isfile, mock_get_module
    ):

        mock_get_max_VF.return_value = '16'
        mock_get_current_VF.return_value = '8'
        mock_get_module.return_value = 'mlx5_core'

        file1 = '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        mock_isfile.return_value = True

        with self.assertRaisesRegexp(InvalidParameter, 'GINNET0084E'):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('iface1', 8)
            mock_isfile.assert_called_once_with(file1)

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_current_VFs')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_sriov_fails_if_VF_and_config_value_is_zero(
        self, mock_get_max_VF, mock_get_current_VF,
        mock_isfile, mock_get_module
    ):

        mock_get_max_VF.return_value = '16'
        mock_get_current_VF.return_value = '0'
        mock_get_module.return_value = 'mlx5_core'

        file1 = '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        mock_isfile.return_value = True

        with self.assertRaisesRegexp(InvalidParameter, 'GINNET0093E'):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('iface1', 0)
            mock_isfile.assert_called_once_with(file1)

    @mock.patch('wok.plugins.ginger.model.interfaces.'
                'add_config_to_mlx5_SRIOV_boot_script')
    @mock.patch('wok.plugins.ginger.model.nw_cfginterfaces_utils.'
                'CfgInterfacesHelper.create_interface_cfg_file')
    @mock.patch('wok.plugins.ginger.model.nw_cfginterfaces_utils.'
                'CfgInterfacesHelper.get_interface_list')
    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_current_VFs')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_success(self, mock_get_max_VF, mock_get_current_VF,
                                mock_isfile, mock_get_module,
                                mock_get_iface_list, mock_create_cfg_file,
                                mock_add_boot_script):

        mock_get_max_VF.return_value = '8'
        mock_get_current_VF.return_value = '2'
        mock_get_module.return_value = 'mlx5_core'

        file1 = '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        mock_isfile.return_value = True

        mock_get_iface_list.side_effect = [
            set(['iface1', 'iface2']),
            set(['iface1', 'sriov1', 'sriov2', 'iface2'])
        ]

        open_ = mock_open(read_data='')

        with patch('__builtin__.open', open_):
            open_.call_args_list = []
            iface_model = InterfaceModel(objstore=self._objstore)
            task_obj = iface_model.enable_sriov('iface1', 4)
            self.task.wait(task_obj['id'])

            finished_task = self.task.lookup(task_obj['id'])
            self.assertEquals(finished_task['status'], 'finished')
            mock_isfile.assert_called_once_with(file1)
            self.assertIn(call(file1, 'w'), open_.call_args_list)
            self.assertEqual(open_().write.mock_calls,
                             [call('0\n'), call('4\n')])

        mock_create_cfg_file.assert_has_calls(
            [call('sriov1'), call('sriov2')]
        )
        mock_add_boot_script.assert_called_once_with('iface1', 4)

    @mock.patch('wok.plugins.ginger.model.interfaces.'
                'add_config_to_mlx5_SRIOV_boot_script')
    @mock.patch('wok.plugins.ginger.model.nw_cfginterfaces_utils.'
                'CfgInterfacesHelper.create_interface_cfg_file')
    @mock.patch('wok.plugins.ginger.model.nw_cfginterfaces_utils.'
                'CfgInterfacesHelper.get_interface_list')
    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_current_VFs')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_success_zero_VFs(self, mock_get_max_VF,
                                         mock_get_current_VF,
                                         mock_isfile, mock_get_module,
                                         mock_get_iface_list,
                                         mock_create_cfg_file,
                                         mock_add_boot_script):

        mock_get_max_VF.return_value = '8'
        mock_get_current_VF.return_value = '4'
        mock_get_module.return_value = 'mlx5_core'

        file1 = '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        mock_isfile.return_value = True

        mock_get_iface_list.side_effect = [
            set(['iface1', 'iface2']),
            set(['iface1', 'sriov1', 'sriov2', 'iface2'])
        ]

        open_ = mock_open(read_data='')

        with patch.object(builtins, 'open', open_):
            iface_model = InterfaceModel(objstore=self._objstore)
            task_obj = iface_model.enable_sriov('iface1', 0)
            self.task.wait(task_obj['id'])

            finished_task = self.task.lookup(task_obj['id'])
            self.assertEquals(finished_task['status'], 'finished')
            mock_isfile.assert_called_once_with(file1)

        self.assertEqual(open_.call_args_list, [call(file1, 'w')])
        self.assertEqual(open_().write.mock_calls, [call('0\n')])
        mock_create_cfg_file.assert_not_called()
        mock_add_boot_script.assert_called_once_with('iface1', 0)

    @mock.patch('os.path.isfile')
    def test_mlx5_sriov_edit_openib_conf(self, mock_isfile):
        openib_conf_file = ifaces_utils.OPENIB_CONF_FILE
        sriov_boot_file = ifaces_utils.MLX5_SRIOV_BOOT_FILE

        conf_file_content = "OPENIBD_PRE_START\nOPENIBD_POST_START\n"\
            "OPENIBD_PRE_STOP\nOPENIBD_POST_STOP\n"

        conf_file_writelines_content = [
            "OPENIBD_PRE_START\n",
            "OPENIBD_POST_START=%s\n" % sriov_boot_file,
            "OPENIBD_PRE_STOP\n",
            "OPENIBD_POST_STOP\n"
        ]

        mock_isfile.return_value = True

        open_ = mock_open(read_data=conf_file_content)

        with patch.object(builtins, 'open', open_):
            ifaces_utils.add_mlx5_SRIOV_boot_script_in_openib_conf()
            mock_isfile.assert_called_once_with(openib_conf_file)

        self.assertEqual(
            open_.call_args_list,
            [call(openib_conf_file, 'r'), call(openib_conf_file, 'w')]
        )
        self.assertEqual(
            open_().writelines.mock_calls,
            [call(conf_file_writelines_content)]
        )

    @mock.patch('os.path.isfile')
    def test_mlx5_sriov_edit_openib_conf_notfound(self, mock_isfile):
        openib_conf_file = ifaces_utils.OPENIB_CONF_FILE

        mock_isfile.return_value = False

        with self.assertRaisesRegexp(OperationFailed, 'GINNET0088E'):
            ifaces_utils.add_mlx5_SRIOV_boot_script_in_openib_conf()
            mock_isfile.assert_called_once_with(openib_conf_file)

    @mock.patch('os.path.isfile')
    def test_mlx5_sriov_openib_conf_variable_notfound(self, mock_isfile):
        openib_conf_file = ifaces_utils.OPENIB_CONF_FILE
        sriov_boot_file = ifaces_utils.MLX5_SRIOV_BOOT_FILE

        conf_file_content = "OPENIBD_PRE_START\n"\
            "OPENIBD_PRE_STOP\nOPENIBD_POST_STOP\n"

        conf_file_write_content = "OPENIBD_POST_START=%s\n" % sriov_boot_file

        mock_isfile.return_value = True

        open_ = mock_open(read_data=conf_file_content)

        with patch.object(builtins, 'open', open_):
            ifaces_utils.add_mlx5_SRIOV_boot_script_in_openib_conf()
            mock_isfile.assert_called_once_with(openib_conf_file)

        self.assertEqual(
            open_.call_args_list,
            [call(openib_conf_file, 'r'), call(openib_conf_file, 'a')]
        )
        self.assertEqual(open_().write.mock_calls,
                         [call(conf_file_write_content)])

    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.'
                'add_mlx5_SRIOV_boot_script_in_openib_conf')
    @mock.patch('os.chmod')
    def test_mlx5_sriov_fresh_boot_script_content(self, mock_chmod,
                                                  mock_add_openib):

        ginger_boot_script = ifaces_utils.MLX5_SRIOV_BOOT_FILE

        template = """#!/bin/sh\n\
# ginger_sriov_start.sh: Connectx-4 SR-IOV init script - created by Ginger\n\
\n# %(iface)s setup\n\
echo 0 > /sys/class/net/%(iface)s/device/sriov_numvfs\n\
echo %(num_vf)s > /sys/class/net/%(iface)s/device/sriov_numvfs\n"""
        interface = 'dummyiface'
        num_vfs = '4'
        template = template % {'iface': interface, 'num_vf': num_vfs}

        open_ = mock_open(read_data='')
        with patch.object(builtins, 'open', open_):
            ifaces_utils.create_initial_mlx5_SRIOV_boot_script(interface,
                                                               num_vfs)

        self.assertEqual(
            open_.call_args_list, [call(ginger_boot_script, 'w+')]
        )
        self.assertEqual(
            open_().write.mock_calls, [call(template)]
        )
        mock_chmod.assert_called_once_with(ginger_boot_script, 0744)
        mock_add_openib.assert_called_once_with()

    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.'
                'add_mlx5_SRIOV_boot_script_in_openib_conf')
    @mock.patch('os.path.isfile')
    def test_update_mlx5_sriov_boot_script_append(self, mock_isfile,
                                                  mock_add_openib):
        ginger_boot_script = ifaces_utils.MLX5_SRIOV_BOOT_FILE
        mock_isfile.return_value = True

        initial_file = """#!/bin/sh\n\
# ginger_sriov_start.sh: Connectx-4 SR-IOV init script - created by Ginger\n\
\n# iface1 setup\n\
echo 0 > /sys/class/net/iface1/device/sriov_numvfs\n\
echo 4 > /sys/class/net/iface1/device/sriov_numvfs\n"""

        expected_writelines = [
            "#!/bin/sh\n",
            "# ginger_sriov_start.sh: Connectx-4 SR-IOV init script - "
            "created by Ginger\n", "\n",
            "# iface1 setup\n",
            "echo 0 > /sys/class/net/iface1/device/sriov_numvfs\n",
            "echo 4 > /sys/class/net/iface1/device/sriov_numvfs\n",
            "# iface2 setup\n",
            "echo 0 > /sys/class/net/iface2/device/sriov_numvfs\n",
            "echo 8 > /sys/class/net/iface2/device/sriov_numvfs\n"
        ]

        open_ = mock_open(read_data=initial_file)
        with patch.object(builtins, 'open', open_):
            ifaces_utils.add_config_to_mlx5_SRIOV_boot_script('iface2',
                                                              8)
            mock_isfile.assert_called_once_with(ginger_boot_script)

        self.assertEqual(
            open_.call_args_list, [call(ginger_boot_script, 'r+')]
        )
        self.assertEqual(
            open_().writelines.mock_calls, [call(expected_writelines)]
        )
        mock_add_openib.assert_called_once_with()

    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.'
                'add_mlx5_SRIOV_boot_script_in_openib_conf')
    @mock.patch('os.path.isfile')
    def test_update_mlx5_sriov_script_modify_line(self, mock_isfile,
                                                  mock_add_openib):
        ginger_boot_script = ifaces_utils.MLX5_SRIOV_BOOT_FILE
        mock_isfile.return_value = True

        initial_file = """#!/bin/sh\n\
# ginger_sriov_start.sh: Connectx-4 SR-IOV init script - created by Ginger\n\
\n# iface1 setup\n\
echo 0 > /sys/class/net/iface1/device/sriov_numvfs\n\
echo 4 > /sys/class/net/iface1/device/sriov_numvfs\n\
# iface2 setup\n\
echo 0 > /sys/class/net/iface2/device/sriov_numvfs\n\
echo 6 > /sys/class/net/iface2/device/sriov_numvfs\n\
# iface3 setup\n\
echo 0 > /sys/class/net/iface3/device/sriov_numvfs\n\
echo 8 > /sys/class/net/iface3/device/sriov_numvfs\n\
# iface4 setup\n\
echo 0 > /sys/class/net/iface4/device/sriov_numvfs\n\
echo 10 > /sys/class/net/iface4/device/sriov_numvfs\n\
"""
        expected_writelines = [
            "#!/bin/sh\n",
            "# ginger_sriov_start.sh: Connectx-4 SR-IOV init script - "
            "created by Ginger\n", "\n",
            "# iface1 setup\n",
            "echo 0 > /sys/class/net/iface1/device/sriov_numvfs\n",
            "echo 4 > /sys/class/net/iface1/device/sriov_numvfs\n",
            "# iface2 setup\n",
            "echo 0 > /sys/class/net/iface2/device/sriov_numvfs\n",
            "echo 6 > /sys/class/net/iface2/device/sriov_numvfs\n",
            "# iface3 setup\n",
            "echo 0 > /sys/class/net/iface3/device/sriov_numvfs\n",
            "echo 2 > /sys/class/net/iface3/device/sriov_numvfs\n",
            "# iface4 setup\n",
            "echo 0 > /sys/class/net/iface4/device/sriov_numvfs\n",
            "echo 10 > /sys/class/net/iface4/device/sriov_numvfs\n",
        ]

        open_ = mock_open(read_data=initial_file)
        with patch.object(builtins, 'open', open_):
            ifaces_utils.add_config_to_mlx5_SRIOV_boot_script('iface3',
                                                              2)
            mock_isfile.assert_called_once_with(ginger_boot_script)

        self.assertEqual(
            open_.call_args_list, [call(ginger_boot_script, 'r+')]
        )
        self.assertEqual(
            open_().writelines.mock_calls, [call(expected_writelines)]
        )
        mock_add_openib.assert_called_once_with()
class PartitionTests(unittest.TestCase):
    def setUp(self):
        objstore_loc = config.get_object_store() + '_ginger'
        self._objstore = ObjectStore(objstore_loc)
        self.task_model = TaskModel(objstore=self._objstore)

    def test_get_part_list(self):
        parts = diskparts.PartitionsModel()
        parts_list = parts.get_list()
        self.assertGreaterEqual(len(parts_list), 0)

    def test_create_part_missing_device(self):
        parts = diskparts.PartitionsModel()
        size = '10M'
        params = {'partsize': size}
        self.assertRaises(MissingParameter, parts.create, params)

    def test_create_part_missing_size(self):
        parts = diskparts.PartitionsModel()
        dev = '/dev/sdb'
        params = {'devname': dev}
        self.assertRaises(MissingParameter, parts.create, params)

    @mock.patch('wok.plugins.ginger.model.utils.create_disk_part',
                autospec=True)
    def test_create_part(self, mock_create_part):
        parts = diskparts.PartitionsModel()
        dev = '/dev/sdb'
        size = '10M'
        params = {'devname': dev, 'partsize': size}
        parts.create(params)
        mock_create_part.return_value = 'sdb1'
        mock_create_part.assert_called_with(dev, size)

    @mock.patch('wok.plugins.ginger.model.utils.change_part_type',
                autospec=True)
    def test_change_part_type(self, mock_change_type):
        part = diskparts.PartitionModel(objstore=self._objstore)
        part_name = 'sdb1'
        type = '82'
        mock_change_type.return_value = 'sdb1'
        part.change_type(part_name, type)
        mock_change_type.assert_called_with(part_name, type)

    @mock.patch('wok.plugins.ginger.model.utils.delete_part',
                autospec=True)
    def test_delete_part(self, mock_delete_part):
        part = diskparts.PartitionModel(objstore=self._objstore)
        part_name = 'sdb1'
        part.delete(part_name)
        mock_delete_part.assert_called_with(part_name)

    @mock.patch('wok.plugins.ginger.model.utils._makefs', autospec=True)
    @mock.patch('wok.plugins.ginger.model.utils._is_mntd', autospec=True)
    def test_format_part(self, mock_is_mntd, mock_makefs):
        mock_is_mntd.return_value = False
        part = diskparts.PartitionModel(objstore=self._objstore)
        name = 'a_partition_name'
        fstype = 'ext4'
        task_obj = part.format(name, fstype)
        self.task_model.wait(task_obj.get('id'))
        mock_makefs.assert_called_with(fstype, name)

    @mock.patch('wok.plugins.ginger.model.diskparts.get_partition_details',
                autospec=True)
    def test_lookup_invalid_part_returns_404(self, mock_get_part_details):
        mock_get_part_details.side_effect = [NotFoundError]

        part = diskparts.PartitionModel(objstore=self._objstore)

        with self.assertRaises(NotFoundError):
            part.lookup('/a/invalid/partition')
class FirmwareTests(unittest.TestCase):
    def setUp(self):
        objstore_loc = config.get_object_store() + "_ginger"
        self._objstore = ObjectStore(objstore_loc)
        self.task = TaskModel(objstore=self._objstore)

    @mock.patch("wok.plugins.ginger.model.firmware.run_command")
    def test_model_lookup(self, mock_run_command):
        return_output = "0 1 2 3 4 5 6 7 8 9 10 11 12 13"
        mock_run_command.return_value = [return_output, "", 0]
        firmware_lookup = FirmwareModel(objstore=self._objstore).lookup()
        mock_run_command.assert_called_once_with("lsmcode")
        self.assertEquals(firmware_lookup, {"level": "5 6 7 8 9 10 11 12 13"})

    @mock.patch("wok.plugins.ginger.model.firmware.run_command")
    def test_model_lookup_with_product_in_output(self, mock_run_command):
        return_output = "0 1 2 3 4 Product 6 7 8 9 10 11 12 13"
        mock_run_command.return_value = [return_output, "", 0]
        firmware_lookup = FirmwareModel(objstore=self._objstore).lookup()
        mock_run_command.assert_called_once_with("lsmcode")
        self.assertEquals(firmware_lookup, {"level": "13"})

    @mock.patch("wok.plugins.ginger.model.firmware.detect_live_vm")
    def test_model_update_fails_with_running_vm(self, mock_detect_vm):
        mock_detect_vm.return_value = True
        with self.assertRaises(OperationFailed):
            FirmwareModel(objstore=self._objstore).upgrade(None, None)

    @mock.patch("wok.plugins.ginger.model.firmware.detect_live_vm")
    @mock.patch("wok.plugins.ginger.model.firmware.run_command")
    def test_model_upgrade(self, mock_run_command, mock_detect_vm):
        mock_detect_vm.return_value = False
        mock_run_command.return_value = ["", "", 0]

        temp = tempfile.NamedTemporaryFile()
        task = FirmwareModel(objstore=self._objstore).upgrade(None, temp.name)
        self.task.wait(task["id"])
        self.assertTrue(mock_run_command.called, msg="Expected call to run_command. Not called")

        task_info = self.task.lookup(task["id"])
        self.assertEquals("finished", task_info["status"])
        self.assertEquals("/plugins/ginger/firmware/upgrade", task_info["target_uri"])

    @mock.patch("wok.plugins.ginger.model.firmware.detect_live_vm")
    @mock.patch("wok.plugins.ginger.model.firmware.run_command")
    def test_model_upgrade_overwrite_perm_false(self, mock_run_command, mock_detect_vm):
        mock_detect_vm.return_value = False
        mock_run_command.return_value = ["", "", 0]

        temp = tempfile.NamedTemporaryFile()
        task = FirmwareModel(objstore=self._objstore).upgrade(None, temp.name, False)
        self.task.wait(task["id"])
        self.assertTrue(mock_run_command.called, msg="Expected call to run_command. Not called")

        task_info = self.task.lookup(task["id"])
        self.assertEquals("finished", task_info["status"])
        self.assertEquals("/plugins/ginger/firmware/upgrade", task_info["target_uri"])

    @mock.patch("wok.plugins.ginger.model.firmware.run_command")
    def test_model_commit(self, mock_run_command):
        mock_run_command.return_value = ["", "", 0]
        command = ["update_flash", "-c"]
        FirmwareModel(objstore=self._objstore).commit(None)
        mock_run_command.assert_called_once_with(command)

    @mock.patch("wok.plugins.ginger.model.firmware.run_command")
    def test_model_reject(self, mock_run_command):
        mock_run_command.return_value = ["", "", 0]
        command = ["update_flash", "-r"]
        FirmwareModel(objstore=self._objstore).reject(None)
        mock_run_command.assert_called_once_with(command)
Exemple #9
0
class InterfacesTests(unittest.TestCase):
    def setUp(self):
        objstore_loc = config.get_object_store() + '_ginger'
        self._objstore = ObjectStore(objstore_loc)
        self.task = TaskModel(objstore=self._objstore)

    @mock.patch('wok.plugins.gingerbase.netinfo.os')
    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_type')
    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.run_command')
    def test_activate(self, mock_run_command, mock_get_interface_type,
                      mock_os):
        mock_run_command.return_value = ["", "", 0]
        mock_os.path.isfile.return_value = False
        open_mock = mock.mock_open(read_data='1')
        mock_get_interface_type.return_value = "nic"
        interface = "test_eth0"
        calls = [(['ip', 'link', 'set',
                   '%s' % interface, 'up'], ), (['ifup',
                                                 '%s' % interface], )]
        with mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.open',
                        open_mock,
                        create=True):
            self.assertRaises(OperationFailed,
                              InterfaceModel(objstore=self._objstore).activate,
                              interface)
        for i in range(0, 1):
            x, y = mock_run_command.call_args_list[i]
            assert x == calls[i]
        assert mock_run_command.call_count == 2

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_type')
    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.run_command')
    def test_activate_fail(self, mock_run_command, mock_get_interface_type):
        mock_run_command.return_value = ["", "Unable to activate", 1]
        mock_get_interface_type.return_value = "nic"
        interface = "test_eth0"
        cmd = ['ip', 'link', 'set', '%s' % interface, 'up']
        self.assertRaises(OperationFailed,
                          InterfaceModel(objstore=self._objstore).activate,
                          interface)
        mock_run_command.assert_called_once_with(cmd)

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_type')
    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.run_command')
    def test_deactivate(self, mock_run_command, mock_get_interface_type):
        mock_run_command.return_value = ["", "", 0]
        mock_get_interface_type.return_value = "nic"
        interface = "test_eth0"
        calls = [(['ifdown', '%s' % interface], ),
                 (['ip', 'link', 'set',
                   '%s' % interface, 'down'], )]
        InterfaceModel(objstore=self._objstore).deactivate(interface)
        for i in range(0, 1):
            x, y = mock_run_command.call_args_list[i]
            assert x == calls[i]
        assert mock_run_command.call_count == 2

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_type')
    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.run_command')
    def test_deactivate_fail(self, mock_run_command, mock_get_interface_type):
        mock_run_command.return_value = ["", "Unable to deactivate", 1]
        mock_get_interface_type.return_value = "nic"
        interface = "test_eth0"
        cmd = ['ifdown', '%s' % interface]
        self.assertRaises(OperationFailed,
                          InterfaceModel(objstore=self._objstore).deactivate,
                          interface)
        mock_run_command.assert_called_once_with(cmd)

    @mock.patch('os.readlink')
    def test_netinfo_interface_module_lookup_success(self, mock_readlink):
        mock_readlink.return_value = '../../../../module/dummy_net_module'

        module = netinfo.get_interface_kernel_module('dummy_iface')
        mock_readlink.assert_called_once_with(
            '/sys/class/net/dummy_iface/device/driver/module')

        self.assertEqual(module, 'dummy_net_module')

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('ethtool.get_devices')
    @mock.patch('ethtool.get_ipaddr')
    @mock.patch('ethtool.get_netmask')
    @mock.patch('wok.plugins.gingerbase.netinfo.macaddr')
    def test_netinfo_get_interface_info(self, mock_macaddr, mock_netmask,
                                        mock_ipaddr, mock_getdevs,
                                        mock_get_module):
        mock_get_module.return_value = 'dummy_net_module'
        mock_getdevs.return_value = ['dev1', 'dummy_iface', 'dev2']
        mock_ipaddr.return_value = '99.99.99.99'
        mock_netmask.return_value = '255.255.255.0'
        mock_macaddr.return_value = 'aa:bb:cc:dd:ee:ff'

        iface_info = netinfo.get_interface_info('dummy_iface')

        mock_macaddr.assert_called_once_with('dummy_iface')
        mock_netmask.assert_called_once_with('dummy_iface')
        mock_ipaddr.assert_called_once_with('dummy_iface')
        mock_getdevs.assert_called_once_with()
        mock_get_module.assert_called_once_with('dummy_iface')

        self.assertEqual(iface_info.get('device'), 'dummy_iface')
        self.assertEqual(iface_info.get('type'), 'unknown')
        self.assertEqual(iface_info.get('status'), 'down')
        self.assertEqual(iface_info.get('ipaddr'), '99.99.99.99')
        self.assertEqual(iface_info.get('netmask'), '255.255.255.0')
        self.assertEqual(iface_info.get('macaddr'), 'aa:bb:cc:dd:ee:ff')
        self.assertEqual(iface_info.get('module'), 'dummy_net_module')

    @mock.patch('ethtool.get_devices')
    @mock.patch('wok.plugins.gingerbase.netinfo.is_rdma_enabled')
    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_info')
    def test_interface_lookup(self, mock_iface_info, mock_rdma_enabled,
                              mock_getdevs):
        iface_info_return = {
            'device': 'dummy_iface',
            'type': 'unknown',
            'status': 'down',
            'ipaddr': '99.99.99.99',
            'netmask': '255.255.255.0',
            'macaddr': 'aa:bb:cc:dd:ee:ff',
            'module': 'dummy_net_module'
        }
        mock_iface_info.return_value = iface_info_return
        mock_rdma_enabled.return_value = True
        mock_getdevs.return_value = ['dev1', 'dummy_iface', 'dev2']

        iface_model = InterfaceModel(objstore=self._objstore)
        iface_info = iface_model.lookup('dummy_iface')
        mock_iface_info.assert_called_once_with('dummy_iface')
        mock_rdma_enabled.assert_called_once_with('dummy_iface')
        mock_getdevs.called_once_with()

        self.assertEqual(iface_info.get('device'), 'dummy_iface')
        self.assertEqual(iface_info.get('type'), 'unknown')
        self.assertEqual(iface_info.get('status'), 'down')
        self.assertEqual(iface_info.get('ipaddr'), '99.99.99.99')
        self.assertEqual(iface_info.get('netmask'), '255.255.255.0')
        self.assertEqual(iface_info.get('macaddr'), 'aa:bb:cc:dd:ee:ff')
        self.assertEqual(iface_info.get('module'), 'dummy_net_module')
        self.assertTrue(iface_info.get('rdma_enabled'))

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    def test_invalid_module_enable_sriov_failure(self, mock_get_module):
        mock_get_module.return_value = 'unknown'

        expected_error_msg = "GINNET0076E"
        with self.assertRaisesRegexp(InvalidOperation, expected_error_msg):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('any_iface_name', {'num_vfs': 4})

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_no_args_failure(self, mock_get_max_VF,
                                        mock_get_module):

        mock_get_max_VF.return_value = '1'
        mock_get_module.return_value = 'mlx5_core'

        expected_error_msg = "GINNET0077E"
        with self.assertRaisesRegexp(InvalidParameter, expected_error_msg):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('any_iface_name', None)

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_argument_failure(self, mock_get_max_VF,
                                         mock_get_module):

        mock_get_max_VF.return_value = '1'
        mock_get_module.return_value = 'mlx5_core'

        expected_error_msg = "GINNET0079E"
        with self.assertRaisesRegexp(InvalidParameter, expected_error_msg):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('any_iface_name', 'not_an_int')

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_no_system_files_failure(self, mock_get_max_VF,
                                                mock_isfile, mock_get_module):
        mock_get_max_VF.return_value = '8'
        mock_get_module.return_value = 'mlx5_core'

        call_file1_not_exist = \
            '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        call_file2_not_exist = \
            '/sys/class/net/%s/device/mlx5_num_vfs' % 'iface1'

        mock_isfile.side_effect = [False, False]

        mock_isfile_calls = [
            call(call_file1_not_exist),
            call(call_file2_not_exist)
        ]

        expected_error_msg = "GINNET0078E"
        with self.assertRaisesRegexp(OperationFailed, expected_error_msg):
            iface_model = InterfaceModel(objstore=self._objstore)
            task_obj = iface_model.enable_sriov('iface1', 4)
            self.task.wait(task_obj['id'])

            mock_isfile.assert_has_calls(mock_isfile_calls)

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    def test_mlx5_sriov_not_enabled_in_FW(self, mock_isfile, mock_get_module):
        mock_get_module.return_value = 'mlx5_core'

        file1 = '/sys/class/net/%s/device/sriov_totalvfs' % 'iface1'
        mock_isfile.return_value = False

        with self.assertRaisesRegexp(OperationFailed, 'GINNET0082E'):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('iface1', 4)
            mock_isfile.assert_called_once_with(file1)

    @mock.patch('os.path.isfile')
    def test_mlx5_sriov_get_maxVF_value(self, mock_isfile):
        file1 = '/sys/class/net/%s/device/sriov_totalvfs' % 'iface1'
        mock_isfile.return_value = True

        open_ = mock_open(read_data='8\n')

        with patch.object(builtins, 'open', open_):
            iface_model = InterfaceModel(objstore=self._objstore)
            max_vf_str = iface_model._mlx5_SRIOV_get_max_VF('iface1')
            mock_isfile.assert_called_once_with(file1)
            self.assertEqual(max_vf_str, '8')

        self.assertEqual(open_.call_args_list, [call(file1, 'r')])

    @mock.patch('os.path.isfile')
    def test_mlx5_sriov_get_currentVF_value(self, mock_isfile):
        file1 = '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        mock_isfile.return_value = True

        open_ = mock_open(read_data='5\n')

        with patch.object(builtins, 'open', open_):
            iface_model = InterfaceModel(objstore=self._objstore)
            curr_vf_str = iface_model._mlx5_SRIOV_get_current_VFs('iface1')
            mock_isfile.assert_called_once_with(file1)
            self.assertEqual(curr_vf_str, '5')

        self.assertEqual(open_.call_args_list, [call(file1, 'r')])

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_fails_if_VF_greater_max(self, mock_get_max_VF,
                                                mock_isfile, mock_get_module):

        mock_get_max_VF.return_value = '8'
        mock_get_module.return_value = 'mlx5_core'

        file1 = '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        mock_isfile.return_value = True

        with self.assertRaisesRegexp(InvalidParameter, 'GINNET0083E'):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('iface1', 16)
            mock_isfile.assert_called_once_with(file1)

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_current_VFs')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_fails_if_VF_equal_to_current(self, mock_get_max_VF,
                                                     mock_get_current_VF,
                                                     mock_isfile,
                                                     mock_get_module):

        mock_get_max_VF.return_value = '16'
        mock_get_current_VF.return_value = '8'
        mock_get_module.return_value = 'mlx5_core'

        file1 = '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        mock_isfile.return_value = True

        with self.assertRaisesRegexp(InvalidParameter, 'GINNET0084E'):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('iface1', 8)
            mock_isfile.assert_called_once_with(file1)

    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_current_VFs')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_sriov_fails_if_VF_and_config_value_is_zero(
            self, mock_get_max_VF, mock_get_current_VF, mock_isfile,
            mock_get_module):

        mock_get_max_VF.return_value = '16'
        mock_get_current_VF.return_value = '0'
        mock_get_module.return_value = 'mlx5_core'

        file1 = '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        mock_isfile.return_value = True

        with self.assertRaisesRegexp(InvalidParameter, 'GINNET0093E'):
            iface_model = InterfaceModel(objstore=self._objstore)
            iface_model.enable_sriov('iface1', 0)
            mock_isfile.assert_called_once_with(file1)

    @mock.patch('wok.plugins.ginger.model.interfaces.'
                'add_config_to_mlx5_SRIOV_boot_script')
    @mock.patch('wok.plugins.ginger.model.nw_cfginterfaces_utils.'
                'CfgInterfacesHelper.create_interface_cfg_file')
    @mock.patch('wok.plugins.ginger.model.nw_cfginterfaces_utils.'
                'CfgInterfacesHelper.get_interface_list')
    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_current_VFs')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_success(self, mock_get_max_VF, mock_get_current_VF,
                                mock_isfile, mock_get_module,
                                mock_get_iface_list, mock_create_cfg_file,
                                mock_add_boot_script):

        mock_get_max_VF.return_value = '8'
        mock_get_current_VF.return_value = '2'
        mock_get_module.return_value = 'mlx5_core'

        file1 = '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        mock_isfile.return_value = True

        mock_get_iface_list.side_effect = [
            set(['iface1', 'iface2']),
            set(['iface1', 'sriov1', 'sriov2', 'iface2'])
        ]

        open_ = mock_open(read_data='')

        with patch.object(builtins, 'open', open_):
            iface_model = InterfaceModel(objstore=self._objstore)
            task_obj = iface_model.enable_sriov('iface1', 4)
            self.task.wait(task_obj['id'])

            finished_task = self.task.lookup(task_obj['id'])
            self.assertEquals(finished_task['status'], 'finished')
            mock_isfile.assert_called_once_with(file1)

        self.assertEqual(open_.call_args_list,
                         [call(file1, 'w'), call(file1, 'w')])
        self.assertEqual(open_().write.mock_calls, [call('0\n'), call('4\n')])
        mock_create_cfg_file.assert_has_calls([call('sriov1'), call('sriov2')])
        mock_add_boot_script.assert_called_once_with('iface1', 4)

    @mock.patch('wok.plugins.ginger.model.interfaces.'
                'add_config_to_mlx5_SRIOV_boot_script')
    @mock.patch('wok.plugins.ginger.model.nw_cfginterfaces_utils.'
                'CfgInterfacesHelper.create_interface_cfg_file')
    @mock.patch('wok.plugins.ginger.model.nw_cfginterfaces_utils.'
                'CfgInterfacesHelper.get_interface_list')
    @mock.patch('wok.plugins.gingerbase.netinfo.get_interface_kernel_module')
    @mock.patch('os.path.isfile')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_current_VFs')
    @mock.patch('wok.plugins.ginger.model.interfaces.InterfaceModel.'
                '_mlx5_SRIOV_get_max_VF')
    def test_mlx5_sriov_success_zero_VFs(self, mock_get_max_VF,
                                         mock_get_current_VF, mock_isfile,
                                         mock_get_module, mock_get_iface_list,
                                         mock_create_cfg_file,
                                         mock_add_boot_script):

        mock_get_max_VF.return_value = '8'
        mock_get_current_VF.return_value = '4'
        mock_get_module.return_value = 'mlx5_core'

        file1 = '/sys/class/net/%s/device/sriov_numvfs' % 'iface1'
        mock_isfile.return_value = True

        mock_get_iface_list.side_effect = [
            set(['iface1', 'iface2']),
            set(['iface1', 'sriov1', 'sriov2', 'iface2'])
        ]

        open_ = mock_open(read_data='')

        with patch.object(builtins, 'open', open_):
            iface_model = InterfaceModel(objstore=self._objstore)
            task_obj = iface_model.enable_sriov('iface1', 0)
            self.task.wait(task_obj['id'])

            finished_task = self.task.lookup(task_obj['id'])
            self.assertEquals(finished_task['status'], 'finished')
            mock_isfile.assert_called_once_with(file1)

        self.assertEqual(open_.call_args_list, [call(file1, 'w')])
        self.assertEqual(open_().write.mock_calls, [call('0\n')])
        mock_create_cfg_file.assert_not_called()
        mock_add_boot_script.assert_called_once_with('iface1', 0)

    @mock.patch('os.path.isfile')
    def test_mlx5_sriov_edit_openib_conf(self, mock_isfile):
        openib_conf_file = ifaces_utils.OPENIB_CONF_FILE
        sriov_boot_file = ifaces_utils.MLX5_SRIOV_BOOT_FILE

        conf_file_content = "OPENIBD_PRE_START\nOPENIBD_POST_START\n"\
            "OPENIBD_PRE_STOP\nOPENIBD_POST_STOP\n"

        conf_file_writelines_content = [
            "OPENIBD_PRE_START\n",
            "OPENIBD_POST_START=%s\n" % sriov_boot_file, "OPENIBD_PRE_STOP\n",
            "OPENIBD_POST_STOP\n"
        ]

        mock_isfile.return_value = True

        open_ = mock_open(read_data=conf_file_content)

        with patch.object(builtins, 'open', open_):
            ifaces_utils.add_mlx5_SRIOV_boot_script_in_openib_conf()
            mock_isfile.assert_called_once_with(openib_conf_file)

        self.assertEqual(
            open_.call_args_list,
            [call(openib_conf_file, 'r'),
             call(openib_conf_file, 'w')])
        self.assertEqual(open_().writelines.mock_calls,
                         [call(conf_file_writelines_content)])

    @mock.patch('os.path.isfile')
    def test_mlx5_sriov_edit_openib_conf_notfound(self, mock_isfile):
        openib_conf_file = ifaces_utils.OPENIB_CONF_FILE

        mock_isfile.return_value = False

        with self.assertRaisesRegexp(OperationFailed, 'GINNET0088E'):
            ifaces_utils.add_mlx5_SRIOV_boot_script_in_openib_conf()
            mock_isfile.assert_called_once_with(openib_conf_file)

    @mock.patch('os.path.isfile')
    def test_mlx5_sriov_openib_conf_variable_notfound(self, mock_isfile):
        openib_conf_file = ifaces_utils.OPENIB_CONF_FILE
        sriov_boot_file = ifaces_utils.MLX5_SRIOV_BOOT_FILE

        conf_file_content = "OPENIBD_PRE_START\n"\
            "OPENIBD_PRE_STOP\nOPENIBD_POST_STOP\n"

        conf_file_write_content = "OPENIBD_POST_START=%s\n" % sriov_boot_file

        mock_isfile.return_value = True

        open_ = mock_open(read_data=conf_file_content)

        with patch.object(builtins, 'open', open_):
            ifaces_utils.add_mlx5_SRIOV_boot_script_in_openib_conf()
            mock_isfile.assert_called_once_with(openib_conf_file)

        self.assertEqual(
            open_.call_args_list,
            [call(openib_conf_file, 'r'),
             call(openib_conf_file, 'a')])
        self.assertEqual(open_().write.mock_calls,
                         [call(conf_file_write_content)])

    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.'
                'add_mlx5_SRIOV_boot_script_in_openib_conf')
    @mock.patch('os.chmod')
    def test_mlx5_sriov_fresh_boot_script_content(self, mock_chmod,
                                                  mock_add_openib):

        ginger_boot_script = ifaces_utils.MLX5_SRIOV_BOOT_FILE

        template = """#!/bin/sh\n\
# ginger_sriov_start.sh: Connectx-4 SR-IOV init script - created by Ginger\n\
\n# %(iface)s setup\n\
echo 0 > /sys/class/net/%(iface)s/device/sriov_numvfs\n\
echo %(num_vf)s > /sys/class/net/%(iface)s/device/sriov_numvfs\n"""
        interface = 'dummyiface'
        num_vfs = '4'
        template = template % {'iface': interface, 'num_vf': num_vfs}

        open_ = mock_open(read_data='')
        with patch.object(builtins, 'open', open_):
            ifaces_utils.create_initial_mlx5_SRIOV_boot_script(
                interface, num_vfs)

        self.assertEqual(open_.call_args_list,
                         [call(ginger_boot_script, 'w+')])
        self.assertEqual(open_().write.mock_calls, [call(template)])
        mock_chmod.assert_called_once_with(ginger_boot_script, 0744)
        mock_add_openib.assert_called_once_with()

    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.'
                'add_mlx5_SRIOV_boot_script_in_openib_conf')
    @mock.patch('os.path.isfile')
    def test_update_mlx5_sriov_boot_script_append(self, mock_isfile,
                                                  mock_add_openib):
        ginger_boot_script = ifaces_utils.MLX5_SRIOV_BOOT_FILE
        mock_isfile.return_value = True

        initial_file = """#!/bin/sh\n\
# ginger_sriov_start.sh: Connectx-4 SR-IOV init script - created by Ginger\n\
\n# iface1 setup\n\
echo 0 > /sys/class/net/iface1/device/sriov_numvfs\n\
echo 4 > /sys/class/net/iface1/device/sriov_numvfs\n"""

        expected_writelines = [
            "#!/bin/sh\n",
            "# ginger_sriov_start.sh: Connectx-4 SR-IOV init script - "
            "created by Ginger\n", "\n", "# iface1 setup\n",
            "echo 0 > /sys/class/net/iface1/device/sriov_numvfs\n",
            "echo 4 > /sys/class/net/iface1/device/sriov_numvfs\n",
            "# iface2 setup\n",
            "echo 0 > /sys/class/net/iface2/device/sriov_numvfs\n",
            "echo 8 > /sys/class/net/iface2/device/sriov_numvfs\n"
        ]

        open_ = mock_open(read_data=initial_file)
        with patch.object(builtins, 'open', open_):
            ifaces_utils.add_config_to_mlx5_SRIOV_boot_script('iface2', 8)
            mock_isfile.assert_called_once_with(ginger_boot_script)

        self.assertEqual(open_.call_args_list,
                         [call(ginger_boot_script, 'r+')])
        self.assertEqual(open_().writelines.mock_calls,
                         [call(expected_writelines)])
        mock_add_openib.assert_called_once_with()

    @mock.patch('wok.plugins.ginger.model.nw_interfaces_utils.'
                'add_mlx5_SRIOV_boot_script_in_openib_conf')
    @mock.patch('os.path.isfile')
    def test_update_mlx5_sriov_script_modify_line(self, mock_isfile,
                                                  mock_add_openib):
        ginger_boot_script = ifaces_utils.MLX5_SRIOV_BOOT_FILE
        mock_isfile.return_value = True

        initial_file = """#!/bin/sh\n\
# ginger_sriov_start.sh: Connectx-4 SR-IOV init script - created by Ginger\n\
\n# iface1 setup\n\
echo 0 > /sys/class/net/iface1/device/sriov_numvfs\n\
echo 4 > /sys/class/net/iface1/device/sriov_numvfs\n\
# iface2 setup\n\
echo 0 > /sys/class/net/iface2/device/sriov_numvfs\n\
echo 6 > /sys/class/net/iface2/device/sriov_numvfs\n\
# iface3 setup\n\
echo 0 > /sys/class/net/iface3/device/sriov_numvfs\n\
echo 8 > /sys/class/net/iface3/device/sriov_numvfs\n\
# iface4 setup\n\
echo 0 > /sys/class/net/iface4/device/sriov_numvfs\n\
echo 10 > /sys/class/net/iface4/device/sriov_numvfs\n\
"""
        expected_writelines = [
            "#!/bin/sh\n",
            "# ginger_sriov_start.sh: Connectx-4 SR-IOV init script - "
            "created by Ginger\n",
            "\n",
            "# iface1 setup\n",
            "echo 0 > /sys/class/net/iface1/device/sriov_numvfs\n",
            "echo 4 > /sys/class/net/iface1/device/sriov_numvfs\n",
            "# iface2 setup\n",
            "echo 0 > /sys/class/net/iface2/device/sriov_numvfs\n",
            "echo 6 > /sys/class/net/iface2/device/sriov_numvfs\n",
            "# iface3 setup\n",
            "echo 0 > /sys/class/net/iface3/device/sriov_numvfs\n",
            "echo 2 > /sys/class/net/iface3/device/sriov_numvfs\n",
            "# iface4 setup\n",
            "echo 0 > /sys/class/net/iface4/device/sriov_numvfs\n",
            "echo 10 > /sys/class/net/iface4/device/sriov_numvfs\n",
        ]

        open_ = mock_open(read_data=initial_file)
        with patch.object(builtins, 'open', open_):
            ifaces_utils.add_config_to_mlx5_SRIOV_boot_script('iface3', 2)
            mock_isfile.assert_called_once_with(ginger_boot_script)

        self.assertEqual(open_.call_args_list,
                         [call(ginger_boot_script, 'r+')])
        self.assertEqual(open_().writelines.mock_calls,
                         [call(expected_writelines)])
        mock_add_openib.assert_called_once_with()
Exemple #10
0
class StorageVolumesModel(object):
    def __init__(self, **kargs):
        self.conn = kargs['conn']
        self.objstore = kargs['objstore']
        self.task = TaskModel(**kargs)

    def create(self, pool_name, params):
        vol_source = ['url', 'capacity']

        name = params.get('name')

        index_list = list(i for i in range(len(vol_source))
                          if vol_source[i] in params)
        if len(index_list) != 1:
            raise InvalidParameter('KCHVOL0018E',
                                   {'param': ','.join(vol_source)})

        create_param = vol_source[index_list[0]]

        # Verify if the URL is valid
        if create_param == 'url':
            url = params['url']
            try:
                urllib.request.urlopen(url).close()
            except Exception:
                raise InvalidParameter('KCHVOL0022E', {'url': url})

        all_vol_names = self.get_list(pool_name)

        if name is None:
            # the methods listed in 'REQUIRE_NAME_PARAMS' cannot have
            # 'name' == None
            if create_param in REQUIRE_NAME_PARAMS:
                raise InvalidParameter('KCHVOL0016E')

            # if 'name' is omitted - except for the methods listed in
            # 'REQUIRE_NAME_PARAMS' - the default volume name will be the
            # file/URL basename.
            if create_param == 'url':
                name = os.path.basename(params['url'])
            else:
                name = f'upload-{int(time.time())}'

            name = get_unique_file_name(all_vol_names, name)
            params['name'] = name

        try:
            create_func = getattr(self, f'_create_volume_with_{create_param}')
        except AttributeError:
            raise InvalidParameter('KCHVOL0019E', {'param': create_param})

        pool_info = StoragePoolModel(conn=self.conn,
                                     objstore=self.objstore).lookup(pool_name)
        if pool_info['type'] in READONLY_POOL_TYPE:
            raise InvalidParameter('KCHVOL0012E', {'type': pool_info['type']})
        if pool_info['state'] == 'inactive':
            raise InvalidParameter('KCHVOL0003E', {
                'pool': pool_name,
                'volume': name
            })
        if name in all_vol_names:
            raise InvalidParameter('KCHVOL0001E', {'name': name})

        params['pool'] = pool_name
        params['pool_type'] = pool_info['type']
        targeturi = '/plugins/kimchi/storagepools/%s/storagevolumes/%s' % (
            pool_name,
            name,
        )
        taskid = AsyncTask(targeturi, create_func, params).id
        return self.task.lookup(taskid)

    def _create_volume_with_capacity(self, cb, params):
        pool_name = params.pop('pool')
        vol_xml = """
        <volume>
          <name>%(name)s</name>
          <allocation unit='bytes'>%(allocation)s</allocation>
          <capacity unit='bytes'>%(capacity)s</capacity>
          <source>
          </source>
          <target>
            <format type='%(format)s'/>
          </target>
        </volume>
        """
        allocation = 0
        if params['pool_type'] == 'logical':
            allocation = params['capacity']
        params.setdefault('allocation', allocation)
        params.setdefault('format', 'qcow2')

        name = params['name']
        try:
            pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
            xml = vol_xml % params
        except KeyError as item:
            raise MissingParameter('KCHVOL0004E', {
                'item': str(item),
                'volume': name
            })

        try:
            pool.createXML(xml, 0)
        except libvirt.libvirtError as e:
            raise OperationFailed(
                'KCHVOL0007E',
                {
                    'name': name,
                    'pool': pool_name,
                    'err': e.get_error_message()
                },
            )

        vol_info = StorageVolumeModel(conn=self.conn,
                                      objstore=self.objstore).lookup(
                                          pool_name, name)
        vol_path = vol_info['path']

        if params.get('upload', False):
            upload_volumes[vol_path] = {
                'lock': threading.Lock(),
                'offset': 0,
                'cb': cb,
                'expected_vol_size': params['capacity'],
            }
            cb('ready for upload')
        else:
            cb('OK', True)

    def _create_volume_with_url(self, cb, params):
        pool_name = params['pool']
        name = params['name']
        url = params['url']

        pool_model = StoragePoolModel(conn=self.conn, objstore=self.objstore)
        pool = pool_model.lookup(pool_name)

        if pool['type'] in ['dir', 'netfs']:
            file_path = os.path.join(pool['path'], name)
        else:
            file_path = tempfile.mkstemp(prefix=name)[1]

        with contextlib.closing(urllib.request.urlopen(url)) as response:
            with open(file_path, 'w') as volume_file:
                remote_size = response.getheader('Content-Length', '-')
                downloaded_size = 0

                try:
                    while True:
                        chunk_data = response.read(READ_CHUNK_SIZE).decode(
                            'utf-8')
                        if not chunk_data:
                            break

                        volume_file.write(chunk_data)
                        downloaded_size += len(chunk_data)
                        cb(f'{downloaded_size}/{remote_size}')
                except (IOError, libvirt.libvirtError) as e:
                    if os.path.isfile(file_path):
                        os.remove(file_path)

                    raise OperationFailed('KCHVOL0007E', {
                        'name': name,
                        'pool': pool_name,
                        'err': str(e)
                    })

        if pool['type'] in ['dir', 'netfs']:
            virt_pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
            virt_pool.refresh(0)
        else:

            def _stream_handler(stream, nbytes, fd):
                return fd.read(nbytes)

            virt_stream = virt_vol = None

            try:
                task = self.create(
                    pool_name,
                    {
                        'name': name,
                        'format': 'raw',
                        'capacity': downloaded_size,
                        'allocation': downloaded_size,
                    },
                )
                self.task.wait(task['id'])
                virt_vol = StorageVolumeModel.get_storagevolume(
                    pool_name, name, self.conn)

                virt_stream = self.conn.get().newStream(0)
                virt_vol.upload(virt_stream, 0, downloaded_size, 0)

                with open(file_path) as fd:
                    virt_stream.sendAll(_stream_handler, fd)

                virt_stream.finish()
            except (IOError, libvirt.libvirtError) as e:
                try:
                    if virt_stream:
                        virt_stream.abort()
                    if virt_vol:
                        virt_vol.delete(0)
                except libvirt.libvirtError as e:
                    wok_log.error(str(e))
                finally:
                    raise OperationFailed('KCHVOL0007E', {
                        'name': name,
                        'pool': pool_name,
                        'err': str(e)
                    })
            finally:
                os.remove(file_path)

        cb('OK', True)

    def get_list(self, pool_name):
        pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
        if not pool.isActive():
            raise InvalidOperation('KCHVOL0006E', {'pool': pool_name})
        try:
            pool.refresh(0)
        except Exception as e:
            wok_log.error(f'Pool refresh failed: {e}')
        return sorted(pool.listVolumes())
Exemple #11
0
class PartitionTests(unittest.TestCase):
    def setUp(self):
        objstore_loc = config.get_object_store() + '_ginger'
        self._objstore = ObjectStore(objstore_loc)
        self.task_model = TaskModel(objstore=self._objstore)

    def test_get_part_list(self):
        parts = diskparts.PartitionsModel()
        parts_list = parts.get_list()
        self.assertGreaterEqual(len(parts_list), 0)

    def test_create_part_missing_device(self):
        parts = diskparts.PartitionsModel()
        size = 10
        params = {'partsize': size}
        self.assertRaises(MissingParameter, parts.create, params)

    def test_create_part_missing_size(self):
        parts = diskparts.PartitionsModel()
        dev = '/dev/sdb'
        params = {'devname': dev}
        self.assertRaises(MissingParameter, parts.create, params)

    @mock.patch('wok.plugins.ginger.model.utils.create_disk_part',
                autospec=True)
    def test_create_part(self, mock_create_part):
        parts = diskparts.PartitionsModel()
        dev = '/dev/sdb'
        size = 10
        params = {'devname': dev, 'partsize': size}
        parts.create(params)
        mock_create_part.return_value = 'sdb1'
        mock_create_part.assert_called_with(dev, size)

    @mock.patch('wok.plugins.ginger.model.utils.change_part_type',
                autospec=True)
    def test_change_part_type(self, mock_change_type):
        part = diskparts.PartitionModel(objstore=self._objstore)
        part_name = 'sdb1'
        type = '82'
        mock_change_type.return_value = 'sdb1'
        part.change_type(part_name, type)
        mock_change_type.assert_called_with(part_name, type)

    @mock.patch('wok.plugins.ginger.model.utils.delete_part', autospec=True)
    def test_delete_part(self, mock_delete_part):
        part = diskparts.PartitionModel(objstore=self._objstore)
        part_name = 'sdb1'
        part.delete(part_name)
        mock_delete_part.assert_called_with(part_name)

    @mock.patch('wok.plugins.ginger.model.utils._makefs', autospec=True)
    @mock.patch('wok.plugins.ginger.model.utils._is_mntd', autospec=True)
    def test_format_part(self, mock_is_mntd, mock_makefs):
        mock_is_mntd.return_value = False
        part = diskparts.PartitionModel(objstore=self._objstore)
        name = 'a_partition_name'
        fstype = 'ext4'
        task_obj = part.format(name, fstype)
        self.task_model.wait(task_obj.get('id'))
        mock_makefs.assert_called_with(fstype, name)

    @mock.patch('wok.plugins.ginger.model.diskparts.get_partition_details',
                autospec=True)
    def test_lookup_invalid_part_returns_404(self, mock_get_part_details):
        mock_get_part_details.side_effect = iter([NotFoundError])

        part = diskparts.PartitionModel(objstore=self._objstore)

        with self.assertRaises(NotFoundError):
            part.lookup('/a/invalid/partition')
Exemple #12
0
class StorageVolumesModel(object):
    def __init__(self, **kargs):
        self.conn = kargs['conn']
        self.objstore = kargs['objstore']
        self.task = TaskModel(**kargs)

    def create(self, pool_name, params):
        vol_source = ['url', 'capacity']

        name = params.get('name')

        index_list = list(i for i in range(len(vol_source))
                          if vol_source[i] in params)
        if len(index_list) != 1:
            raise InvalidParameter(
                'KCHVOL0018E', {'param': ','.join(vol_source)})

        create_param = vol_source[index_list[0]]

        # Verify if the URL is valid
        if create_param == 'url':
            url = params['url']
            try:
                urllib.request.urlopen(url).close()
            except Exception:
                raise InvalidParameter('KCHVOL0022E', {'url': url})

        all_vol_names = self.get_list(pool_name)

        if name is None:
            # the methods listed in 'REQUIRE_NAME_PARAMS' cannot have
            # 'name' == None
            if create_param in REQUIRE_NAME_PARAMS:
                raise InvalidParameter('KCHVOL0016E')

            # if 'name' is omitted - except for the methods listed in
            # 'REQUIRE_NAME_PARAMS' - the default volume name will be the
            # file/URL basename.
            if create_param == 'url':
                name = os.path.basename(params['url'])
            else:
                name = f'upload-{int(time.time())}'

            name = get_unique_file_name(all_vol_names, name)
            params['name'] = name

        try:
            create_func = getattr(self, f'_create_volume_with_{create_param}')
        except AttributeError:
            raise InvalidParameter('KCHVOL0019E', {'param': create_param})

        pool_info = StoragePoolModel(conn=self.conn, objstore=self.objstore).lookup(
            pool_name
        )
        if pool_info['type'] in READONLY_POOL_TYPE:
            raise InvalidParameter('KCHVOL0012E', {'type': pool_info['type']})
        if pool_info['state'] == 'inactive':
            raise InvalidParameter(
                'KCHVOL0003E', {'pool': pool_name, 'volume': name})
        if name in all_vol_names:
            raise InvalidParameter('KCHVOL0001E', {'name': name})

        params['pool'] = pool_name
        params['pool_type'] = pool_info['type']
        targeturi = '/plugins/kimchi/storagepools/%s/storagevolumes/%s' % (
            pool_name,
            name,
        )
        taskid = AsyncTask(targeturi, create_func, params).id
        return self.task.lookup(taskid)

    def _create_volume_with_capacity(self, cb, params):
        pool_name = params.pop('pool')
        vol_xml = """
        <volume>
          <name>%(name)s</name>
          <allocation unit='bytes'>%(allocation)s</allocation>
          <capacity unit='bytes'>%(capacity)s</capacity>
          <source>
          </source>
          <target>
            <format type='%(format)s'/>
          </target>
        </volume>
        """
        allocation = 0
        if params['pool_type'] == 'logical':
            allocation = params['capacity']
        params.setdefault('allocation', allocation)
        params.setdefault('format', 'qcow2')

        name = params['name']
        try:
            pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
            xml = vol_xml % params
        except KeyError as item:
            raise MissingParameter(
                'KCHVOL0004E', {'item': str(item), 'volume': name})

        try:
            pool.createXML(xml, 0)
        except libvirt.libvirtError as e:
            raise OperationFailed(
                'KCHVOL0007E',
                {'name': name, 'pool': pool_name, 'err': e.get_error_message()},
            )

        vol_info = StorageVolumeModel(conn=self.conn, objstore=self.objstore).lookup(
            pool_name, name
        )
        vol_path = vol_info['path']

        if params.get('upload', False):
            upload_volumes[vol_path] = {
                'lock': threading.Lock(),
                'offset': 0,
                'cb': cb,
                'expected_vol_size': params['capacity'],
            }
            cb('ready for upload')
        else:
            cb('OK', True)

    def _create_volume_with_url(self, cb, params):
        pool_name = params['pool']
        name = params['name']
        url = params['url']

        pool_model = StoragePoolModel(conn=self.conn, objstore=self.objstore)
        pool = pool_model.lookup(pool_name)

        if pool['type'] in ['dir', 'netfs']:
            file_path = os.path.join(pool['path'], name)
        else:
            file_path = tempfile.mkstemp(prefix=name)[1]

        with contextlib.closing(urllib.request.urlopen(url)) as response:
            with open(file_path, 'w') as volume_file:
                remote_size = response.getheader('Content-Length', '-')
                downloaded_size = 0

                try:
                    while True:
                        chunk_data = response.read(
                            READ_CHUNK_SIZE).decode('utf-8')
                        if not chunk_data:
                            break

                        volume_file.write(chunk_data)
                        downloaded_size += len(chunk_data)
                        cb(f'{downloaded_size}/{remote_size}')
                except (IOError, libvirt.libvirtError) as e:
                    if os.path.isfile(file_path):
                        os.remove(file_path)

                    raise OperationFailed(
                        'KCHVOL0007E', {'name': name,
                                        'pool': pool_name, 'err': str(e)}
                    )

        if pool['type'] in ['dir', 'netfs']:
            virt_pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
            virt_pool.refresh(0)
        else:

            def _stream_handler(stream, nbytes, fd):
                return fd.read(nbytes)

            virt_stream = virt_vol = None

            try:
                task = self.create(
                    pool_name,
                    {
                        'name': name,
                        'format': 'raw',
                        'capacity': downloaded_size,
                        'allocation': downloaded_size,
                    },
                )
                self.task.wait(task['id'])
                virt_vol = StorageVolumeModel.get_storagevolume(
                    pool_name, name, self.conn
                )

                virt_stream = self.conn.get().newStream(0)
                virt_vol.upload(virt_stream, 0, downloaded_size, 0)

                with open(file_path) as fd:
                    virt_stream.sendAll(_stream_handler, fd)

                virt_stream.finish()
            except (IOError, libvirt.libvirtError) as e:
                try:
                    if virt_stream:
                        virt_stream.abort()
                    if virt_vol:
                        virt_vol.delete(0)
                except libvirt.libvirtError as e:
                    wok_log.error(str(e))
                finally:
                    raise OperationFailed(
                        'KCHVOL0007E', {'name': name,
                                        'pool': pool_name, 'err': str(e)}
                    )
            finally:
                os.remove(file_path)

        cb('OK', True)

    def get_list(self, pool_name):
        pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
        if not pool.isActive():
            raise InvalidOperation('KCHVOL0006E', {'pool': pool_name})
        try:
            pool.refresh(0)
        except Exception as e:
            wok_log.error(f'Pool refresh failed: {e}')
        return sorted(pool.listVolumes())
Exemple #13
0
class BackupArchiveTests(unittest.TestCase):

    def setUp(self):
        self.temp_file = tempfile.NamedTemporaryFile(delete=False)
        objstore_loc = self.temp_file.name
        self._objstore = ObjectStore(objstore_loc)

        self.task = TaskModel(objstore=self._objstore)

        ArchivesModel._archive_dir = '/tmp'
        ArchivesModel._default_include = []
        ArchivesModel._default_exclude = []

    def tearDown(self):
        self.temp_file.close()
        os.remove(self.temp_file.name)

    @mock.patch('wok.plugins.ginger.model.backup.run_command')
    @mock.patch('wok.plugins.ginger.model.backup.get_tar_create_timeout')
    @mock.patch('wok.plugins.ginger.model.backup._sha256sum')
    def test_create_and_lookup_backup_file(self, mock_sha256sum,
                                           mock_timeout, mock_run_command):
        include = []
        exclude = []
        descr = 'test_create_lookup_bkp_file'
        mock_run_command.return_value = ["", "", 0]
        mock_timeout.return_value = 10
        mock_sha256sum.return_value = 'sha256sum'

        params = {'include': [], 'exclude': [], 'description': descr}
        task_obj = ArchivesModel(objstore=self._objstore).create(params)
        self.task.wait(task_obj['id'])

        archive_id = task_obj['target_uri'].split("/")[-1]
        archive_file = os.path.join('/tmp', archive_id + '.tar.gz')

        cmd = ['tar', '--create', '--gzip', '--absolute-names',
               '--file', archive_file, '--selinux', '--acl',
               '--xattrs'] + exclude + include

        mock_run_command.asert_called_once_with(cmd)
        mock_sha256sum.asert_called_once_with(archive_file)

        lookup = ArchiveModel(objstore=self._objstore).lookup(archive_id)

        self.assertEqual(lookup.get('identity'), archive_id)
        self.assertEqual(lookup.get('include'), [])
        self.assertEqual(lookup.get('exclude'), [])
        self.assertEqual(lookup.get('description'), descr)
        self.assertEqual(lookup.get('file'), archive_file)

    @mock.patch('wok.objectstore.ObjectStoreSession.delete')
    @mock.patch('wok.plugins.ginger.model.backup.ArchivesModel.'
                '_session_get_list')
    @mock.patch('os.listdir')
    def test_archive_list_removes_deleted_tar_entries(self, mock_listdir,
                                                      mock_get_list,
                                                      mock_session_delete):

        mock_listdir.return_value = ['file1.tar.gz', 'file3.tar.gz']
        mock_get_list.return_value = ['file1', 'file2', 'file3', 'file4']

        ArchivesModel(objstore=self._objstore).get_list()

        mock_listdir.assert_called_once_with(ArchivesModel._archive_dir)
        mock_session_delete.assert_has_calls(
            [
                call(ArchivesModel._objstore_type, 'file2'),
                call(ArchivesModel._objstore_type, 'file4')
            ]
        )
Exemple #14
0
class FirmwareTests(unittest.TestCase):
    def setUp(self):
        objstore_loc = config.get_object_store() + '_ginger'
        self._objstore = ObjectStore(objstore_loc)
        self.task = TaskModel(objstore=self._objstore)

    @mock.patch('wok.plugins.ginger.model.firmware.run_command')
    def test_model_lookup(self, mock_run_command):
        return_output = "0 1 2 3 4 5 6 7 8 9 10 11 12 13"
        mock_run_command.return_value = [return_output, "", 0]
        firmware_lookup = FirmwareModel(objstore=self._objstore).lookup()
        mock_run_command.assert_called_once_with('lsmcode')
        self.assertEquals(firmware_lookup, {'level': "5 6 7 8 9 10 11 12 13"})

    @mock.patch('wok.plugins.ginger.model.firmware.run_command')
    def test_model_lookup_with_product_in_output(self, mock_run_command):
        return_output = "0 1 2 3 4 Product 6 7 8 9 10 11 12 13"
        mock_run_command.return_value = [return_output, "", 0]
        firmware_lookup = FirmwareModel(objstore=self._objstore).lookup()
        mock_run_command.assert_called_once_with('lsmcode')
        self.assertEquals(firmware_lookup, {'level': '13'})

    @mock.patch('wok.plugins.ginger.model.firmware.detect_live_vm')
    def test_model_update_fails_with_running_vm(self, mock_detect_vm):
        mock_detect_vm.return_value = True
        with self.assertRaises(OperationFailed):
            FirmwareModel(objstore=self._objstore).upgrade(None, None)

    @mock.patch('wok.plugins.ginger.model.firmware.detect_live_vm')
    @mock.patch('wok.plugins.ginger.model.firmware.run_command')
    def test_model_upgrade(self, mock_run_command, mock_detect_vm):
        mock_detect_vm.return_value = False
        mock_run_command.return_value = ["", "", 0]

        temp = tempfile.NamedTemporaryFile()
        task = FirmwareModel(objstore=self._objstore).upgrade(None, temp.name)
        self.task.wait(task['id'])
        self.assertTrue(mock_run_command.called,
                        msg='Expected call to run_command. Not called')

        task_info = self.task.lookup(task['id'])
        self.assertEquals('finished', task_info['status'])
        self.assertEquals('/plugins/ginger/firmware/upgrade',
                          task_info['target_uri'])

    @mock.patch('wok.plugins.ginger.model.firmware.detect_live_vm')
    @mock.patch('wok.plugins.ginger.model.firmware.run_command')
    def test_model_upgrade_overwrite_perm_false(self, mock_run_command,
                                                mock_detect_vm):
        mock_detect_vm.return_value = False
        mock_run_command.return_value = ["", "", 0]

        temp = tempfile.NamedTemporaryFile()
        task = FirmwareModel(objstore=self._objstore).upgrade(
            None, temp.name, False)
        self.task.wait(task['id'])
        self.assertTrue(mock_run_command.called,
                        msg='Expected call to run_command. Not called')

        task_info = self.task.lookup(task['id'])
        self.assertEquals('finished', task_info['status'])
        self.assertEquals('/plugins/ginger/firmware/upgrade',
                          task_info['target_uri'])

    @mock.patch('wok.plugins.ginger.model.firmware.run_command')
    def test_model_commit(self, mock_run_command):
        mock_run_command.return_value = ["", "", 0]
        command = ['update_flash', '-c']
        FirmwareModel(objstore=self._objstore).commit(None)
        mock_run_command.assert_called_once_with(command)

    @mock.patch('wok.plugins.ginger.model.firmware.run_command')
    def test_model_reject(self, mock_run_command):
        mock_run_command.return_value = ["", "", 0]
        command = ['update_flash', '-r']
        FirmwareModel(objstore=self._objstore).reject(None)
        mock_run_command.assert_called_once_with(command)
Exemple #15
0
class FirmwareTests(unittest.TestCase):

    def setUp(self):
        objstore_loc = config.get_object_store() + '_ginger'
        self._objstore = ObjectStore(objstore_loc)
        self.task = TaskModel(objstore=self._objstore)

    @mock.patch('wok.plugins.ginger.model.firmware.run_command')
    def test_model_lookup(self, mock_run_command):
        return_output = "0 1 2 3 4 5 6 7 8 9 10 11 12 13"
        mock_run_command.return_value = [return_output, "", 0]
        firmware_lookup = FirmwareModel(objstore=self._objstore).lookup()
        mock_run_command.assert_called_once_with('lsmcode')
        self.assertEquals(
            firmware_lookup,
            {'level': "5 6 7 8 9 10 11 12 13"}
        )

    @mock.patch('wok.plugins.ginger.model.firmware.run_command')
    def test_model_lookup_with_product_in_output(self, mock_run_command):
        return_output = "0 1 2 3 4 Product 6 7 8 9 10 11 12 13"
        mock_run_command.return_value = [return_output, "", 0]
        firmware_lookup = FirmwareModel(objstore=self._objstore).lookup()
        mock_run_command.assert_called_once_with('lsmcode')
        self.assertEquals(firmware_lookup, {'level': '13'})

    @mock.patch('wok.plugins.ginger.model.firmware.detect_live_vm')
    def test_model_update_fails_with_running_vm(self, mock_detect_vm):
        mock_detect_vm.return_value = True
        with self.assertRaises(OperationFailed):
            FirmwareModel(objstore=self._objstore).upgrade(None, None)

    @mock.patch('wok.plugins.ginger.model.firmware.detect_live_vm')
    @mock.patch('wok.plugins.ginger.model.firmware.run_command')
    def test_model_update(self, mock_run_command, mock_detect_vm):
        mock_detect_vm.return_value = False
        mock_run_command.return_value = ["", "", 0]

        temp = tempfile.NamedTemporaryFile()
        command = ['update_flash', '-f', temp.name]

        task = FirmwareModel(objstore=self._objstore).upgrade(temp.name)
        self.task.wait(task['id'])
        mock_run_command.assert_called_once_with(
            command,
            tee='/tmp/fw_tee_log.txt'
        )

    @mock.patch('wok.plugins.ginger.model.firmware.detect_live_vm')
    @mock.patch('wok.plugins.ginger.model.firmware.run_command')
    def test_model_update_overwrite_perm_false(
        self,
        mock_run_command,
        mock_detect_vm
    ):

        mock_detect_vm.return_value = False
        mock_run_command.return_value = ["", "", 0]

        temp = tempfile.NamedTemporaryFile()
        command = ['update_flash', '-n', '-f', temp.name]

        task = FirmwareModel(objstore=self._objstore).upgrade(temp.name,
                                                              False)
        self.task.wait(task['id'])
        mock_run_command.assert_called_once_with(
            command,
            tee='/tmp/fw_tee_log.txt'
        )

    @mock.patch('wok.plugins.ginger.model.firmware.run_command')
    def test_model_commit(self, mock_run_command):
        mock_run_command.return_value = ["", "", 0]
        command = ['update_flash', '-c']
        FirmwareModel(objstore=self._objstore).commit(None)
        mock_run_command.assert_called_once_with(command)

    @mock.patch('wok.plugins.ginger.model.firmware.run_command')
    def test_model_reject(self, mock_run_command):
        mock_run_command.return_value = ["", "", 0]
        command = ['update_flash', '-r']
        FirmwareModel(objstore=self._objstore).reject(None)
        mock_run_command.assert_called_once_with(command)
Exemple #16
0
class BackupArchiveTests(unittest.TestCase):
    def setUp(self):
        self.temp_file = tempfile.NamedTemporaryFile(delete=False)
        objstore_loc = self.temp_file.name
        self._objstore = ObjectStore(objstore_loc)

        self.task = TaskModel(objstore=self._objstore)

        ArchivesModel._archive_dir = '/tmp'
        ArchivesModel._default_include = []
        ArchivesModel._default_exclude = []

    def tearDown(self):
        self.temp_file.close()
        os.remove(self.temp_file.name)

    @mock.patch('wok.plugins.ginger.model.backup.run_command')
    @mock.patch('wok.plugins.ginger.model.backup._sha256sum')
    def test_create_and_lookup_backup_file(self, mock_sha256sum,
                                           mock_run_command):
        include = []
        exclude = []
        descr = 'test_create_lookup_bkp_file'
        mock_run_command.return_value = ["", "", 0]
        mock_sha256sum.return_value = 'sha256sum'

        params = {'include': [], 'exclude': [], 'description': descr}
        task_obj = ArchivesModel(objstore=self._objstore).create(params)
        self.task.wait(task_obj['id'])

        archive_id = task_obj['target_uri'].split("/")[-1]
        archive_file = os.path.join('/tmp', archive_id + '.tar.gz')

        cmd = [
            'tar', '--create', '--ignore-failed-read', '--gzip',
            '--absolute-names', '--file', archive_file, '--selinux', '--acl',
            '--xattrs'
        ] + exclude + include

        mock_run_command.asert_called_once_with(cmd)
        mock_sha256sum.asert_called_once_with(archive_file)

        lookup = ArchiveModel(objstore=self._objstore).lookup(archive_id)

        self.assertEqual(lookup.get('identity'), archive_id)
        self.assertEqual(lookup.get('include'), [])
        self.assertEqual(lookup.get('exclude'), [])
        self.assertEqual(lookup.get('description'), descr)
        self.assertEqual(lookup.get('file'), archive_file)

    @mock.patch('wok.objectstore.ObjectStoreSession.delete')
    @mock.patch('wok.plugins.ginger.model.backup.ArchivesModel.'
                '_session_get_list')
    @mock.patch('os.listdir')
    def test_archive_list_removes_deleted_tar_entries(self, mock_listdir,
                                                      mock_get_list,
                                                      mock_session_delete):

        mock_listdir.return_value = ['file1.tar.gz', 'file3.tar.gz']
        mock_get_list.return_value = ['file1', 'file2', 'file3', 'file4']

        ArchivesModel(objstore=self._objstore).get_list()

        mock_listdir.assert_called_once_with(ArchivesModel._archive_dir)
        mock_session_delete.assert_has_calls([
            call(ArchivesModel._objstore_type, 'file2'),
            call(ArchivesModel._objstore_type, 'file4')
        ])