Ejemplo n.º 1
0
 def setUp(self, mock_device):
     self.device = mock_device
     self.irf_port = IrfPort(self.device)
     self.irf_member = IrfMember(self.device)
Ejemplo n.º 2
0
class IrfTestCase(BaseFeatureCase):
    @mock.patch('pyhpecw7.comware.HPCOM7')
    def setUp(self, mock_device):
        self.device = mock_device
        self.irf_port = IrfPort(self.device)
        self.irf_member = IrfMember(self.device)

    @mock.patch.object(IrfPort, '_build_iface_updown')
    def test_ports_build(self, mock_iface_updown):
        expected_port_build = self.read_config_xml('irf_port_build')
        expected_activate = self.read_action_xml('irf_port_build_activate')

        expected_call_list = [[expected_port_build, 'edit_config'],
                              ['startup.cfg', 'save'],
                              [expected_activate, 'action']]

        down_ifaces = set([
            'FortyGigE1/0/2', 'FortyGigE1/0/1', 'FortyGigE1/0/3',
            'FortyGigE1/0/4'
        ])
        up_ifaces = set([
            'FortyGigE1/0/1', 'FortyGigE1/0/2', 'FortyGigE1/0/3',
            'FortyGigE1/0/4'
        ])

        self.irf_port.build('1', [], [], ['FortyGigE1/0/1', 'FortyGigE1/0/2'],
                            ['FortyGigE1/0/3', 'FortyGigE1/0/4'])

        self.assert_stage_requests_multiple(expected_call_list)
        mock_iface_updown.assert_has_calls(
            [mock.call(down_ifaces, 'down'),
             mock.call(up_ifaces, 'up')])

    @mock.patch.object(IrfPort, '_build_iface_updown')
    def test_ports_build_remove(self, mock_iface_updown):
        expected_port_build = self.read_config_xml('irf_port_build_remove')
        expected_activate = self.read_action_xml('irf_port_build_activate')

        expected_call_list = [[expected_port_build, 'edit_config'],
                              ['startup.cfg', 'save'],
                              [expected_activate, 'action']]

        down_ifaces = set([
            'FortyGigE1/0/2', 'FortyGigE1/0/1', 'FortyGigE1/0/3',
            'FortyGigE1/0/4'
        ])
        up_ifaces = set()

        self.irf_port.build('1', ['FortyGigE1/0/1', 'FortyGigE1/0/2'],
                            ['FortyGigE1/0/3', 'FortyGigE1/0/4'], [], [])

        self.assert_stage_requests_multiple(expected_call_list)
        mock_iface_updown.assert_has_calls(
            [mock.call(down_ifaces, 'down'),
             mock.call(up_ifaces, 'up')])

    def test_ports_get_config(self):
        expected_get, get_reply = self.xml_get_and_reply('irf_ports')
        self.device.get.return_value = get_reply

        expected = {
            '1': {
                'irf_p2': ['FortyGigE1/0/3', 'FortyGigE1/0/4'],
                'irf_p1': ['FortyGigE1/0/1', 'FortyGigE1/0/2']
            }
        }

        result = self.irf_port.get_config()

        self.assertEqual(result, expected)
        self.assert_get_request(expected_get)

    @mock.patch('pyhpecw7.features.irf.Interface')
    def test_ports_iface_updown(self, mock_interface):
        mock_iface_instance = mock_interface.return_value
        mock_iface_instance.iface_exists = True

        self.irf_port._build_iface_updown(['FortyGigE1/0/1'], 'up')
        mock_iface_instance.build.assert_called_with(admin='up', stage=True)

        mock_iface_instance.iface_exists = False
        with self.assertRaises(InterfaceAbsentError):
            self.irf_port._build_iface_updown(['FortyGigE1/0/1'], 'up')

    def test_member_get_member_config(self):
        expected_get, get_reply = self.xml_get_and_reply('irf_member_config')
        self.device.get.return_value = get_reply

        expected = {
            'new_member_id': '1',
            'priority': '4',
            'descr': 'They used to call me HP1'
        }

        result = self.irf_member._get_member_config('1')

        self.assertEqual(result, expected)
        self.assert_get_request(expected_get)

    def test_member_build_member_config(self):
        expected_call_list = [[
            'irf member 1 description From unit test', 'cli_config'
        ], ['irf member 1 renumber 2', 'cli_config'],
                              ['irf member 1 priority 3', 'cli_config']]

        result = self.irf_member._build_member_config(member_id='1',
                                                      new_member_id='2',
                                                      priority='3',
                                                      descr='From unit test')

        self.assert_stage_requests_multiple(expected_call_list)
        self.assertTrue(result)

    def test_member_get_domain_config(self):
        expected_get, get_reply = self.xml_get_and_reply(
            'irf_member_domain_config')
        self.device.get.return_value = get_reply

        expected = {'domain_id': '1'}

        result = self.irf_member._get_domain_config()

        self.assertEqual(result, expected)
        self.assert_get_request(expected_get)

    def test_member_get_au_config(self):
        expected_get, get_reply = self.xml_get_and_reply(
            'irf_member_au_config')
        self.device.get.return_value = get_reply

        expected = {'auto_update': 'enable'}

        result = self.irf_member._get_auto_update_config()

        self.assertEqual(result, expected)
        self.assert_get_request(expected_get)

    def test_member_build_au_domain_config(self):
        result = self.irf_member._build_auto_update_domain_config(
            'enable', '2')
        expected_call = self.read_config_xml('irf_member_au_domain')

        self.assert_stage_request(expected_call, 'edit_config')
        self.assertTrue(result)

    def test_member_get_mad_exclude(self):
        self.device.cli_display.return_value = '<HP1>display current | inc "mad exclude interface"\r\n mad exclude interface FortyGigE1/0/9\r\n mad exclude interface FortyGigE1/0/10\r\n'
        result = self.irf_member._get_mad_exclude()

        self.device.cli_display.assert_called_with(
            'display current | inc "mad exclude interface"')
        self.assertEqual(
            result, {'mad_exclude': ['FortyGigE1/0/9', 'FortyGigE1/0/10']})

    @mock.patch('pyhpecw7.features.irf.Interface')
    def test_member_build_mad_exclude(self, mock_interface):
        mock_iface_instance = mock_interface.return_value
        mock_iface_instance.iface_exists = True
        mock_iface_instance.interface_name = 'FortyGigE1/0/9'

        result = self.irf_member._build_mad_exclude(['FortyGigE1/0/9'])
        self.assert_stage_request('mad exclude interface FortyGigE1/0/9',
                                  'cli_config')

        mock_iface_instance.iface_exists = False
        with self.assertRaises(InterfaceAbsentError):
            self.irf_member._build_mad_exclude(['FortyGigE1/0/9'])

    @mock.patch.object(IrfMember, '_get_member_config')
    @mock.patch.object(IrfMember, '_get_domain_config')
    @mock.patch.object(IrfMember, '_get_mad_exclude')
    @mock.patch.object(IrfMember, '_get_auto_update_config')
    def test_member_get_config(self, mock_au, mock_mad, mock_domain,
                               mock_member):
        mock_member.return_value = {'a': 1}
        mock_domain.return_value = {'b': 2}
        mock_mad.return_value = {'c': 3}
        mock_au.return_value = {'d': 4}

        result = self.irf_member.get_config('1')
        expected = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

        self.assertEqual(result, expected)

        mock_member.return_value = None
        with self.assertRaises(IRFMemberDoesntExistError):
            self.irf_member.get_config('1')

    @mock.patch.object(IrfMember, '_build_member_config')
    @mock.patch.object(IrfMember, '_build_auto_update_domain_config')
    @mock.patch.object(IrfMember, '_build_mad_exclude')
    def test_member_build(self, mock_mad, mock_au_domain, mock_member):
        params = dict(auto_update='disable',
                      mad_exclude=['FortyGigE1/0/9', 'FortyGigE1/0/10'],
                      member_id='1',
                      new_member_id='1',
                      domain_id='4',
                      priority='2',
                      descr='Configured from unit test.')

        result = self.irf_member.build(**params)

        mock_member.assert_called_with(**params)
        mock_au_domain.assert_called_with('disable', '4')
        mock_mad.assert_called_with(['FortyGigE1/0/9', 'FortyGigE1/0/10'])

        self.assertTrue(result)

    def test_remove_mad_exclude(self):
        iface_list = ['FortyGigE1/0/9', 'FortyGigE1/0/10']
        self.irf_member.remove_mad_exclude(iface_list)

        self.assert_stage_requests_multiple([
            ['undo mad exclude interface FortyGigE1/0/9', 'cli_config'],
            ['undo mad exclude interface FortyGigE1/0/10', 'cli_config'],
        ])
Ejemplo n.º 3
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            member_id=dict(type='str',
                           required=True),
            new_member_id=dict(type='str'),
            auto_update=dict(choices=['enable', 'disable']),
            domain_id=dict(type='str'),
            mad_exclude=dict(),
            priority=dict(type='str'),
            descr=dict(),
            reboot=dict(type='bool',
                        choices=BOOLEANS,
                        required=True),
            state=dict(choices=['present', 'absent'],
                       default='present'),
            hostname=dict(required=True),
            username=dict(required=True),
            password=dict(required=True),
            port=dict(type='int', default=830)
        ),
        supports_check_mode=True
    )

    if not HAS_PYHP:
        module.fail_json(
            msg='There was a problem loading from the pyhpecw7comware module')

    filtered_keys = ('hostname', 'username', 'password',
                     'port', 'CHECKMODE')

    hostname = socket.gethostbyname(module.params['hostname'])
    username = module.params['username']
    password = module.params['password']
    port = module.params['port']

    device = HPCOM7(host=hostname, username=username,
                    password=password, port=port)

    member_id = module.params.pop('member_id')
    reboot = module.params.pop('reboot')
    state = module.params.get('state')

    changed = False

    try:
        device.open()
    except ConnectionError as e:
        safe_fail(module, device, msg=str(e))

    try:
        irfm = IrfMember(device)
        existing = irfm.get_config(member_id)
    except PYHPError as e:
        if isinstance(e, IRFMemberDoesntExistError):
            new_member_id = module.params.get('new_member_id')
            try:
                if new_member_id:
                    member_id = new_member_id
                    irfm = IrfMember(device)
                    existing = irfm.get_config(member_id)
                else:
                    safe_fail(module, device, msg=str(e))
            except PYHPError as e:
                safe_fail(module, device, msg=str(e))
        else:
            safe_fail(module, device, msg=str(e))

    proposed = dict((k, v) for k, v in module.params.items()
                    if v is not None and k not in filtered_keys)

    mad_exclude = proposed.pop('mad_exclude', [])
    if isinstance(mad_exclude, str):
        mad_exclude = [mad_exclude]

    if mad_exclude:
        try:
            mad_exclude = convert_iface_list(device, mad_exclude)
        except InterfaceError as ie:
            module.fail_json(msg=str(ie))

    existing_mad_exclude = existing.pop('mad_exclude', [])
    mad_delta = list(set(mad_exclude).difference(
        existing_mad_exclude))

    delta =  dict(set(proposed.items()) - set(existing.items()))

    proposed['mad_exclude'] = mad_exclude
    existing['mad_exclude'] = existing_mad_exclude

    if state == 'present':
        if delta or mad_delta:
            try:
                irfm.build(
                    member_id=member_id, mad_exclude=mad_delta, **delta)
            except PYHPError as e:
                safe_fail(module, device, msg=str(e),
                          descr='There was an error preparing the'
                          + ' IRF membership configuration.')
    elif state == 'absent':
        remove_mad = list(set(mad_exclude).intersection(
            existing_mad_exclude))
        irfm.remove_mad_exclude(remove_mad)

    commands = None
    end_state = existing

    if device.staged:
        commands = device.staged_to_string()
        if module.check_mode:
            safe_exit(module, device, changed=True,
                      commands=commands)
        else:
            try:
                device.execute_staged()
                end_state = irfm.get_config(member_id)
            except PYHPError as e:
                safe_fail(module, device, msg=str(e))
            changed = True

    results = {}
    results['proposed'] = proposed
    results['existing'] = existing
    results['commands'] = commands
    results['changed'] = changed
    results['end_state'] = end_state
    results['state'] = state

    new_member_id = proposed.get('new_member_id')
    mem_id_changed = False
    if new_member_id:
        mem_id_changed = proposed.get('new_member_id') != member_id
    
    if reboot and mem_id_changed:
        try:
            my_reboot = Reboot(device)
            my_reboot.build(reboot=True)
            changed = True
            device.execute_staged()
        except PYHPError as e:
            if isinstance(e, NCTimeoutError)\
                    or isinstance(e, ConnectionClosedError):
                module.exit_json(**results)
            else:
                safe_fail(module, device, msg=str(e))

    safe_exit(module, device, **results)
def main():
    module = AnsibleModule(
        argument_spec=dict(
            member_id=dict(type='str',
                           required=True),
            new_member_id=dict(type='str'),
            auto_update=dict(choices=['enable', 'disable']),
            domain_id=dict(type='str'),
            mad_exclude=dict(),
            priority=dict(type='str'),
            descr=dict(),
            reboot=dict(type='bool',
                        choices=BOOLEANS,
                        required=True),
            state=dict(choices=['present', 'absent'],
                       default='present'),
            hostname=dict(required=True),
            username=dict(required=True),
            password=dict(required=True),
            port=dict(type='int', default=830)
        ),
        supports_check_mode=True
    )

    if not HAS_PYHP:
        module.fail_json(
            msg='There was a problem loading from the pyhpecw7comware module')

    filtered_keys = ('hostname', 'username', 'password',
                     'port', 'CHECKMODE')

    hostname = socket.gethostbyname(module.params['hostname'])
    username = module.params['username']
    password = module.params['password']
    port = module.params['port']

    device = HPCOM7(host=hostname, username=username,
                    password=password, port=port)

    member_id = module.params.pop('member_id')
    reboot = module.params.pop('reboot')
    state = module.params.get('state')

    changed = False

    try:
        device.open()
    except ConnectionError as e:
        safe_fail(module, device, msg=str(e))

    try:
        irfm = IrfMember(device)
        existing = irfm.get_config(member_id)
    except PYHPError as e:
        if isinstance(e, IRFMemberDoesntExistError):
            new_member_id = module.params.get('new_member_id')
            try:
                if new_member_id:
                    member_id = new_member_id
                    irfm = IrfMember(device)
                    existing = irfm.get_config(member_id)
                else:
                    safe_fail(module, device, msg=str(e))
            except PYHPError as e:
                safe_fail(module, device, msg=str(e))
        else:
            safe_fail(module, device, msg=str(e))

    proposed = dict((k, v) for k, v in module.params.iteritems()
                    if v is not None and k not in filtered_keys)

    mad_exclude = proposed.pop('mad_exclude', [])
    if isinstance(mad_exclude, str):
        mad_exclude = [mad_exclude]

    if mad_exclude:
        try:
            mad_exclude = convert_iface_list(device, mad_exclude)
        except InterfaceError as ie:
            module.fail_json(msg=str(ie))

    existing_mad_exclude = existing.pop('mad_exclude', [])
    mad_delta = list(set(mad_exclude).difference(
        existing_mad_exclude))

    delta = dict(set(proposed.iteritems()).difference(
        existing.iteritems()))

    proposed['mad_exclude'] = mad_exclude
    existing['mad_exclude'] = existing_mad_exclude

    if state == 'present':
        if delta or mad_delta:
            try:
                irfm.build(
                    member_id=member_id, mad_exclude=mad_delta, **delta)
            except PYHPError as e:
                safe_fail(module, device, msg=str(e),
                          descr='There was an error preparing the'
                          + ' IRF membership configuration.')
    elif state == 'absent':
        remove_mad = list(set(mad_exclude).intersection(
            existing_mad_exclude))
        irfm.remove_mad_exclude(remove_mad)

    commands = None
    end_state = existing

    if device.staged:
        commands = device.staged_to_string()
        if module.check_mode:
            safe_exit(module, device, changed=True,
                      commands=commands)
        else:
            try:
                device.execute()
                end_state = irfm.get_config(member_id)
            except PYHPError as e:
                safe_fail(module, device, msg=str(e))
            changed = True

    results = {}
    results['proposed'] = proposed
    results['existing'] = existing
    results['commands'] = commands
    results['changed'] = changed
    results['end_state'] = end_state
    results['state'] = state

    new_member_id = proposed.get('new_member_id')
    mem_id_changed = False
    if new_member_id:
        mem_id_changed = proposed.get('new_member_id') != member_id
    
    if reboot and mem_id_changed:
        try:
            my_reboot = Reboot(device)
            my_reboot.build(reboot=True)
            changed = True
            device.execute()
        except PYHPError as e:
            if isinstance(e, NCTimeoutError)\
                    or isinstance(e, ConnectionClosedError):
                module.exit_json(**results)
            else:
                safe_fail(module, device, msg=str(e))

    safe_exit(module, device, **results)
Ejemplo n.º 5
0
 def setUp(self, mock_device):
     self.device = mock_device
     self.irf_port = IrfPort(self.device)
     self.irf_member = IrfMember(self.device)
Ejemplo n.º 6
0
class IrfTestCase(BaseFeatureCase):

    @mock.patch('pyhpecw7.comware.HPCOM7')
    def setUp(self, mock_device):
        self.device = mock_device
        self.irf_port = IrfPort(self.device)
        self.irf_member = IrfMember(self.device)

    @mock.patch.object(IrfPort, '_build_iface_updown')
    def test_ports_build(self, mock_iface_updown):
        expected_port_build = self.read_config_xml('irf_port_build')
        expected_activate = self.read_action_xml('irf_port_build_activate')

        expected_call_list = [
            [expected_port_build, 'edit_config'],
            ['startup.cfg', 'save'],
            [expected_activate, 'action']

        ]

        down_ifaces = ['FortyGigE1/0/2', 'FortyGigE1/0/1', 'FortyGigE1/0/3', 'FortyGigE1/0/4']
        up_ifaces = ['FortyGigE1/0/1', 'FortyGigE1/0/2', 'FortyGigE1/0/3', 'FortyGigE1/0/4']

        self.irf_port.build('1', [], [], ['FortyGigE1/0/1', 'FortyGigE1/0/2'], ['FortyGigE1/0/3', 'FortyGigE1/0/4'])

        self.assert_stage_requests_multiple(expected_call_list)
        mock_iface_updown.assert_has_calls([mock.call(down_ifaces, 'down'), mock.call(up_ifaces, 'up')])

    @mock.patch.object(IrfPort, '_build_iface_updown')
    def test_ports_build_remove(self, mock_iface_updown):
        expected_port_build = self.read_config_xml('irf_port_build_remove')
        expected_activate = self.read_action_xml('irf_port_build_activate')

        expected_call_list = [
            [expected_port_build, 'edit_config'],
            ['startup.cfg', 'save'],
            [expected_activate, 'action']

        ]

        down_ifaces = ['FortyGigE1/0/2', 'FortyGigE1/0/1', 'FortyGigE1/0/3', 'FortyGigE1/0/4']
        up_ifaces = []

        self.irf_port.build('1', ['FortyGigE1/0/1', 'FortyGigE1/0/2'], ['FortyGigE1/0/3', 'FortyGigE1/0/4'], [], [])

        self.assert_stage_requests_multiple(expected_call_list)
        mock_iface_updown.assert_has_calls([mock.call(down_ifaces, 'down'), mock.call(up_ifaces, 'up')])

    def test_ports_get_config(self):
        expected_get, get_reply = self.xml_get_and_reply('irf_ports')
        self.device.get.return_value = get_reply

        expected = {'1': {'irf_p2': ['FortyGigE1/0/3', 'FortyGigE1/0/4'], 'irf_p1': ['FortyGigE1/0/1', 'FortyGigE1/0/2']}}

        result = self.irf_port.get_config()

        self.assertEqual(result, expected)
        self.assert_get_request(expected_get)

    @mock.patch('pyhpecw7.features.irf.Interface')
    def test_ports_iface_updown(self, mock_interface):
        mock_iface_instance = mock_interface.return_value
        mock_iface_instance.iface_exists = True

        self.irf_port._build_iface_updown(['FortyGigE1/0/1'], 'up')
        mock_iface_instance.build.assert_called_with(admin='up', stage=True)

        mock_iface_instance.iface_exists = False
        with self.assertRaises(InterfaceAbsentError):
            self.irf_port._build_iface_updown(['FortyGigE1/0/1'], 'up')

    def test_member_get_member_config(self):
        expected_get, get_reply = self.xml_get_and_reply('irf_member_config')
        self.device.get.return_value = get_reply

        expected = {'new_member_id': '1', 'priority': '4', 'descr': 'They used to call me HP1'}

        result = self.irf_member._get_member_config('1')

        self.assertEqual(result, expected)
        self.assert_get_request(expected_get)

    def test_member_build_member_config(self):
        expected_call_list = [
            ['irf member 1 description From unit test', 'cli_config'],
            ['irf member 1 renumber 2', 'cli_config'],
            ['irf member 1 priority 3', 'cli_config']
        ]

        result = self.irf_member._build_member_config(member_id='1', new_member_id='2', priority='3', descr='From unit test')

        self.assert_stage_requests_multiple(expected_call_list)
        self.assertTrue(result)

    def test_member_get_domain_config(self):
        expected_get, get_reply = self.xml_get_and_reply('irf_member_domain_config')
        self.device.get.return_value = get_reply

        expected = {'domain_id': '1'}

        result = self.irf_member._get_domain_config()

        self.assertEqual(result, expected)
        self.assert_get_request(expected_get)

    def test_member_get_au_config(self):
        expected_get, get_reply = self.xml_get_and_reply('irf_member_au_config')
        self.device.get.return_value = get_reply

        expected = {'auto_update': 'enable'}

        result = self.irf_member._get_auto_update_config()

        self.assertEqual(result, expected)
        self.assert_get_request(expected_get)

    def test_member_build_au_domain_config(self):
        result = self.irf_member._build_auto_update_domain_config('enable', '2')
        expected_call = self.read_config_xml('irf_member_au_domain')

        self.assert_stage_request(expected_call, 'edit_config')
        self.assertTrue(result)

    def test_member_get_mad_exclude(self):
        self.device.cli_display.return_value = '<HP1>display current | inc "mad exclude interface"\r\n mad exclude interface FortyGigE1/0/9\r\n mad exclude interface FortyGigE1/0/10\r\n'
        result = self.irf_member._get_mad_exclude()

        self.device.cli_display.assert_called_with('display current | inc "mad exclude interface"')
        self.assertEqual(result, {'mad_exclude': ['FortyGigE1/0/9', 'FortyGigE1/0/10']})

    @mock.patch('pyhpecw7.features.irf.Interface')
    def test_member_build_mad_exclude(self, mock_interface):
        mock_iface_instance = mock_interface.return_value
        mock_iface_instance.iface_exists = True
        mock_iface_instance.interface_name = 'FortyGigE1/0/9'

        result = self.irf_member._build_mad_exclude(['FortyGigE1/0/9'])
        self.assert_stage_request('mad exclude interface FortyGigE1/0/9', 'cli_config')

        mock_iface_instance.iface_exists = False
        with self.assertRaises(InterfaceAbsentError):
            self.irf_member._build_mad_exclude(['FortyGigE1/0/9'])

    @mock.patch.object(IrfMember, '_get_member_config')
    @mock.patch.object(IrfMember, '_get_domain_config')
    @mock.patch.object(IrfMember, '_get_mad_exclude')
    @mock.patch.object(IrfMember, '_get_auto_update_config')
    def test_member_get_config(self, mock_au, mock_mad, mock_domain, mock_member):
        mock_member.return_value = {'a': 1}
        mock_domain.return_value = {'b': 2}
        mock_mad.return_value = {'c': 3}
        mock_au.return_value = {'d': 4}

        result = self.irf_member.get_config('1')
        expected = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

        self.assertEqual(result, expected)

        mock_member.return_value = None
        with self.assertRaises(IRFMemberDoesntExistError):
            self.irf_member.get_config('1')

    @mock.patch.object(IrfMember, '_build_member_config')
    @mock.patch.object(IrfMember, '_build_auto_update_domain_config')
    @mock.patch.object(IrfMember, '_build_mad_exclude')
    def test_member_build(self, mock_mad, mock_au_domain, mock_member):
        params = dict(
            auto_update='disable',
            mad_exclude=['FortyGigE1/0/9', 'FortyGigE1/0/10'],
            member_id='1',
            new_member_id='1',
            domain_id='4',
            priority='2',
            descr='Configured from unit test.'
        )

        result = self.irf_member.build(**params)

        mock_member.assert_called_with(**params)
        mock_au_domain.assert_called_with('disable', '4')
        mock_mad.assert_called_with(['FortyGigE1/0/9', 'FortyGigE1/0/10'])

        self.assertTrue(result)

    def test_remove_mad_exclude(self):
        iface_list = ['FortyGigE1/0/9', 'FortyGigE1/0/10']
        self.irf_member.remove_mad_exclude(iface_list)

        self.assert_stage_requests_multiple(
            [
                ['undo mad exclude interface FortyGigE1/0/9', 'cli_config'],
                ['undo mad exclude interface FortyGigE1/0/10', 'cli_config'],
            ]
        )