def test_init_des_iface_infos_only(self): ifaces = Ifaces( cur_iface_infos=[], des_iface_infos=self._gen_iface_infos() ) assert [ i.original_dict for i in ifaces.values() ] == self._gen_iface_infos()
def test_verify_desire_iface_matches(self): cur_iface_infos = self._gen_iface_infos() des_iface_infos = self._gen_iface_infos() des_iface_infos[0].pop(Interface.TYPE) des_ifaces = Ifaces(des_iface_infos, cur_iface_infos) des_ifaces.verify(cur_iface_infos)
def test_verify_desire_iface_not_match(self): cur_iface_infos = self._gen_iface_infos() des_iface_infos = self._gen_iface_infos() des_iface_infos[0][Interface.MAC] = MAC_ADDRESS1 des_ifaces = Ifaces(des_iface_infos, cur_iface_infos) with pytest.raises(NmstateVerificationError): des_ifaces.verify(cur_iface_infos)
def test_state_to_edit_with_changed_only(self): cur_iface_infos = self._gen_iface_infos() ifaces = Ifaces([], cur_iface_infos) for iface in ifaces.values(): iface.mark_as_changed() assert sorted([i[Interface.NAME] for i in ifaces.state_to_edit ]) == sorted([FOO1_IFACE_NAME, FOO2_IFACE_NAME])
def test_verify_desire_iface_not_found_in_current(self): cur_iface_infos = self._gen_iface_infos() cur_iface_infos.pop() des_iface_infos = self._gen_iface_infos() des_ifaces = Ifaces(des_iface_infos, []) with pytest.raises(NmstateVerificationError): des_ifaces.verify(cur_iface_infos)
def test_remove_unknown_interfaces(self): des_iface_infos = self._gen_iface_infos() cur_iface_info = { Interface.NAME: FOO3_IFACE_NAME, Interface.TYPE: InterfaceType.UNKNOWN, Interface.STATE: InterfaceState.UP, } ifaces = Ifaces(des_iface_infos, [cur_iface_info]) assert cur_iface_info not in ifaces.values()
def test_add_new_iface(self): cur_iface_infos = self._gen_iface_infos() new_iface_info = gen_foo_iface_info() new_iface_info[Interface.NAME] = FOO3_IFACE_NAME ifaces = Ifaces([new_iface_info], cur_iface_infos) new_iface = ifaces[FOO3_IFACE_NAME] iface1 = ifaces[FOO1_IFACE_NAME] iface2 = ifaces[FOO2_IFACE_NAME] assert len(ifaces.current_ifaces) == len(self._gen_iface_infos()) assert len(list(ifaces.keys())) == len(self._gen_iface_infos()) + 1 assert new_iface.is_desired assert not iface1.is_desired assert not iface2.is_desired
def test_gen_metadata_save_bond_port_config_to_slave_iface(self): br_iface_info = self._gen_iface_info_with_bond() slave1_iface_info = gen_foo_iface_info() slave1_iface_info[Interface.NAME] = SLAVE1_IFACE_NAME slave2_iface_info = gen_foo_iface_info() slave2_iface_info[Interface.NAME] = SLAVE2_IFACE_NAME ifaces = Ifaces( des_iface_infos=[ br_iface_info, slave1_iface_info, slave2_iface_info, ], cur_iface_infos=[slave1_iface_info, slave2_iface_info], ) br_iface = ifaces[OVS_BRIDGE_IFACE_NAME] br_iface.gen_metadata(ifaces) br_iface.pre_edit_validation_and_cleanup() slave1_iface = ifaces[SLAVE1_IFACE_NAME] slave2_iface = ifaces[SLAVE2_IFACE_NAME] assert slave1_iface.master == OVS_BRIDGE_IFACE_NAME assert slave2_iface.master == OVS_BRIDGE_IFACE_NAME assert (slave1_iface.to_dict()[OvsBridgeIface.BRPORT_OPTIONS_METADATA] == BOND_PORT_CONFIG) assert (slave2_iface.to_dict()[OvsBridgeIface.BRPORT_OPTIONS_METADATA] == BOND_PORT_CONFIG)
def test_state_to_edit_with_desire(self): cur_iface_infos = self._gen_iface_infos() des_iface_infos = self._gen_iface_infos() ifaces = Ifaces(des_iface_infos, cur_iface_infos) assert sorted([i[Interface.NAME] for i in ifaces.state_to_edit ]) == sorted([FOO1_IFACE_NAME, FOO2_IFACE_NAME])
def test_skip_metadata_generation_when_is_absent(self): br_iface_info = gen_bridge_iface_info() br_iface_info[Interface.STATE] = InterfaceState.ABSENT slave1_iface_info = gen_foo_iface_info() slave1_iface_info[Interface.NAME] = SLAVE1_IFACE_NAME slave2_iface_info = gen_foo_iface_info() slave2_iface_info[Interface.NAME] = SLAVE2_IFACE_NAME ifaces = Ifaces( des_iface_infos=[ br_iface_info, slave1_iface_info, slave2_iface_info, ], cur_iface_infos=[], ) br_iface = ifaces[LINUX_BRIDGE_IFACE_NAME] br_iface.gen_metadata(ifaces) br_iface.pre_edit_validation_and_cleanup() slave1_iface = ifaces[SLAVE1_IFACE_NAME] slave2_iface = ifaces[SLAVE2_IFACE_NAME] assert slave1_iface.master is None assert slave2_iface.master is None assert (LinuxBridgeIface.BRPORT_OPTIONS_METADATA not in slave1_iface.to_dict()) assert (LinuxBridgeIface.BRPORT_OPTIONS_METADATA not in slave2_iface.to_dict())
def test_pre_edit_clean_up_discard_mac_address_when_mac_restricted(self): cur_iface_info = self._gen_iface_info() cur_iface_info[Interface.MAC] = MAC_ADDRESS1 iface_info = self._gen_iface_info() iface_info[Bond.CONFIG_SUBTREE][Bond.MODE] = BondMode.ACTIVE_BACKUP iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = { "fail_over_mac": "active" } expected_iface_info = deepcopy(iface_info) ifaces = Ifaces( des_iface_infos=[ iface_info, self._gen_slave1_iface_info(), self._gen_slave2_iface_info(), ], cur_iface_infos=[ cur_iface_info, self._gen_slave1_iface_info(), self._gen_slave2_iface_info(), ], ) bond_iface = ifaces[FOO_IFACE_NAME] bond_iface.gen_metadata(ifaces) bond_iface.pre_edit_validation_and_cleanup() assert expected_iface_info == _remove_metadata(bond_iface.to_dict())
def test_get_is_bond_mode_changed(self): cur_iface_info = self._gen_iface_info() iface_info = self._gen_iface_info() iface_info[Bond.CONFIG_SUBTREE][Bond.MODE] = BondMode.ACTIVE_BACKUP ifaces = Ifaces( des_iface_infos=[ iface_info, self._gen_slave1_iface_info(), self._gen_slave2_iface_info(), ], cur_iface_infos=[ cur_iface_info, self._gen_slave1_iface_info(), self._gen_slave2_iface_info(), ], ) bond_iface = ifaces[FOO_IFACE_NAME] bond_iface.gen_metadata(ifaces) slave1_iface = ifaces[SLAVE1_IFACE_NAME] slave2_iface = ifaces[SLAVE2_IFACE_NAME] assert slave1_iface.master == FOO_IFACE_NAME assert slave2_iface.master == FOO_IFACE_NAME assert bond_iface.is_bond_mode_changed
def test_mark_child_as_absent_when_parent_is_marked_as_absent(self): cur_iface_infos = self._gen_iface_infos() cur_iface_infos[0][Interface.NAME] = PARENT_IFACE_NAME child_iface_info = gen_foo_iface_info(iface_type=InterfaceType.VLAN) child_iface_info[Interface.NAME] = CHILD_IFACE_NAME child_iface_info[VLAN.CONFIG_SUBTREE] = { VLAN.ID: 101, VLAN.BASE_IFACE: PARENT_IFACE_NAME, } cur_iface_infos.append(child_iface_info) des_iface_info = gen_foo_iface_info() des_iface_info[Interface.NAME] = PARENT_IFACE_NAME des_iface_info[Interface.STATE] = InterfaceState.ABSENT ifaces = Ifaces([des_iface_info], cur_iface_infos) child_iface = ifaces[CHILD_IFACE_NAME] parent_iface = ifaces[PARENT_IFACE_NAME] other_iface = ifaces[FOO2_IFACE_NAME] assert parent_iface.is_desired assert child_iface.is_changed assert not other_iface.is_changed assert parent_iface.is_absent assert child_iface.is_absent assert other_iface.is_up
def test_mark_orphen_as_absent(self): """ When OVS internal interface been removed from OVS bridge slave list, the orphen interface should be marked as absent. """ cur_iface_infos = self._gen_iface_infos() cur_iface_infos[0][Interface.NAME] = SLAVE1_IFACE_NAME cur_iface_infos[1][Interface.NAME] = SLAVE2_IFACE_NAME cur_iface_infos.append(gen_ovs_bridge_info()) child_iface_info = gen_foo_iface_info( iface_type=InterfaceType.OVS_INTERFACE ) child_iface_info[Interface.NAME] = OVS_IFACE_NAME cur_iface_infos.append(child_iface_info) des_ovs_bridge_info = gen_ovs_bridge_info() ovs_bridge_iface = OvsBridgeIface(des_ovs_bridge_info) ovs_bridge_iface.remove_slave(OVS_IFACE_NAME) des_iface_info = ovs_bridge_iface.to_dict() ifaces = Ifaces([des_iface_info], cur_iface_infos) ovs_iface = ifaces[OVS_IFACE_NAME] bridge_iface = ifaces[OVS_BRIDGE_IFACE_NAME] slave1_iface = ifaces[SLAVE1_IFACE_NAME] slave2_iface = ifaces[SLAVE2_IFACE_NAME] assert bridge_iface.is_desired assert ovs_iface.is_changed assert not slave1_iface.is_changed assert not slave2_iface.is_changed assert bridge_iface.is_up assert slave1_iface.is_up assert slave2_iface.is_up assert ovs_iface.is_absent
def test_pre_edit_clean_up_discard_bond_options_when_mode_chagned(self): cur_iface_info = self._gen_iface_info() cur_iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = { "miimon": 140 } iface_info = self._gen_iface_info() iface_info[Bond.CONFIG_SUBTREE][Bond.MODE] = BondMode.ACTIVE_BACKUP iface_info[Bond.CONFIG_SUBTREE][Bond.OPTIONS_SUBTREE] = { "arp_interval": 140 } expected_iface_info = deepcopy(iface_info) ifaces = Ifaces( des_iface_infos=[ iface_info, self._gen_slave1_iface_info(), self._gen_slave2_iface_info(), ], cur_iface_infos=[ cur_iface_info, self._gen_slave1_iface_info(), self._gen_slave2_iface_info(), ], ) bond_iface = ifaces[FOO_IFACE_NAME] bond_iface.gen_metadata(ifaces) bond_iface.pre_edit_validation_and_cleanup() assert expected_iface_info == _remove_metadata(bond_iface.to_dict())
def test_validate_unknown_parent(self): child_iface_info = gen_foo_iface_info(iface_type=InterfaceType.VLAN) child_iface_info[VLAN.CONFIG_SUBTREE] = { VLAN.ID: 101, VLAN.BASE_IFACE: PARENT_IFACE_NAME, } with pytest.raises(NmstateValueError): Ifaces([child_iface_info], [])
def _gen_ifaces(self, bond_iface_info): return Ifaces( des_iface_infos=[ bond_iface_info, self._gen_slave1_iface_info(), self._gen_slave2_iface_info(), ], cur_iface_infos=[], )
def gen_two_static_ip_ifaces(iface1_name, iface2_name): iface1_info = gen_foo_iface_info_static_ip() iface1_info[Interface.NAME] = iface1_name iface1_info[Interface.IPV4][InterfaceIPv4.ADDRESS].pop(1) iface1_info[Interface.IPV6][InterfaceIPv6.ADDRESS].pop(1) iface2_info = gen_foo_iface_info_static_ip() iface2_info[Interface.NAME] = iface2_name iface2_info[Interface.IPV4][InterfaceIPv4.ADDRESS].pop(0) iface2_info[Interface.IPV6][InterfaceIPv6.ADDRESS].pop(0) return Ifaces([], [iface1_info, iface2_info])
def test_validate_overbooked_slaves(self): cur_iface_infos = self._gen_iface_infos() cur_iface_infos[0][Interface.NAME] = SLAVE1_IFACE_NAME cur_iface_infos[1][Interface.NAME] = SLAVE2_IFACE_NAME des_iface_info1 = gen_bridge_iface_info() des_iface_info2 = gen_bridge_iface_info() des_iface_info2[Interface.NAME] = "another_bridge" with pytest.raises(NmstateValueError): Ifaces([des_iface_info1, des_iface_info2], cur_iface_infos)
def test_edit_existing_iface(self): cur_iface_infos = self._gen_iface_infos() des_iface_infos = self._gen_iface_infos() des_iface_infos[0][Interface.MAC] = MAC_ADDRESS1 expected_iface_info = deepcopy(des_iface_infos[0]) ifaces = Ifaces(des_iface_infos, cur_iface_infos) edit_iface = ifaces[des_iface_infos[0][Interface.NAME]] assert state_match(expected_iface_info, edit_iface.to_dict()) assert edit_iface.is_desired
def test_mark_iface_as_absent(self): cur_iface_infos = self._gen_iface_infos() des_iface_infos = self._gen_iface_infos() des_iface_infos[0][Interface.STATE] = InterfaceState.ABSENT expected_iface_info = deepcopy(des_iface_infos[0]) ifaces = Ifaces(des_iface_infos, cur_iface_infos) edit_iface = ifaces[des_iface_infos[0][Interface.NAME]] assert state_match(expected_iface_info, edit_iface.to_dict()) assert edit_iface.is_desired assert edit_iface.is_absent
def test_mark_slave_as_changed_when_enslaved_to_new_master(self): cur_iface_infos = self._gen_iface_infos() cur_iface_infos[0][Interface.NAME] = SLAVE1_IFACE_NAME cur_iface_infos[1][Interface.NAME] = SLAVE2_IFACE_NAME des_iface_info = gen_bridge_iface_info() ifaces = Ifaces([des_iface_info], cur_iface_infos) slave_iface1 = ifaces[SLAVE1_IFACE_NAME] slave_iface2 = ifaces[SLAVE2_IFACE_NAME] master_iface = ifaces[LINUX_BRIDGE_IFACE_NAME] assert slave_iface1.is_changed assert slave_iface2.is_changed assert slave_iface1.is_up assert slave_iface2.is_up assert slave_iface1.master == LINUX_BRIDGE_IFACE_NAME assert slave_iface2.master == LINUX_BRIDGE_IFACE_NAME assert master_iface.is_desired
def test_auto_create_ovs_interface(self): iface_info = gen_ovs_bridge_info() slave1_iface_info = gen_foo_iface_info() slave1_iface_info[Interface.NAME] = SLAVE1_IFACE_NAME slave2_iface_info = gen_foo_iface_info() slave2_iface_info[Interface.NAME] = SLAVE2_IFACE_NAME ifaces = Ifaces( des_iface_infos=[ iface_info, slave1_iface_info, slave2_iface_info, ], cur_iface_infos=[slave1_iface_info, slave2_iface_info], ) ovs_iface = ifaces[OVS_IFACE_NAME] assert ovs_iface.type == InterfaceType.OVS_INTERFACE assert ovs_iface.parent == OVS_BRIDGE_IFACE_NAME assert ovs_iface.is_virtual assert ovs_iface.master == OVS_BRIDGE_IFACE_NAME
def test_mark_slave_as_changed_when_master_changed_slave_config(self): cur_iface_infos = self._gen_iface_infos() cur_iface_infos[0][Interface.NAME] = SLAVE1_IFACE_NAME cur_iface_infos[1][Interface.NAME] = SLAVE2_IFACE_NAME cur_iface_infos.append(gen_bridge_iface_info()) des_iface_info = gen_bridge_iface_info() des_iface_info[LinuxBridge.CONFIG_SUBTREE][ LinuxBridge.PORT_SUBTREE][0][LinuxBridge.Port.STP_PATH_COST] += 1 ifaces = Ifaces([des_iface_info], cur_iface_infos) slave_iface1 = ifaces[SLAVE1_IFACE_NAME] slave_iface2 = ifaces[SLAVE2_IFACE_NAME] master_iface = ifaces[LINUX_BRIDGE_IFACE_NAME] assert slave_iface1.is_changed assert not slave_iface2.is_changed assert slave_iface1.is_up assert slave_iface2.is_up assert slave_iface1.master == LINUX_BRIDGE_IFACE_NAME assert slave_iface2.master == LINUX_BRIDGE_IFACE_NAME assert master_iface.is_desired
def test_mark_slave_as_changed_if_master_marked_as_absent(self): cur_iface_infos = self._gen_iface_infos() cur_iface_infos[0][Interface.NAME] = SLAVE1_IFACE_NAME cur_iface_infos[1][Interface.NAME] = SLAVE2_IFACE_NAME cur_iface_infos.append(gen_bridge_iface_info()) des_iface_info = gen_bridge_iface_info() des_iface_info[Interface.STATE] = InterfaceState.ABSENT ifaces = Ifaces([des_iface_info], cur_iface_infos) slave_iface1 = ifaces[SLAVE1_IFACE_NAME] slave_iface2 = ifaces[SLAVE2_IFACE_NAME] master_iface = ifaces[LINUX_BRIDGE_IFACE_NAME] assert slave_iface1.is_changed assert slave_iface2.is_changed assert slave_iface1.is_up assert slave_iface2.is_up assert slave_iface1.master is None assert slave_iface2.master is None assert master_iface.is_desired assert master_iface.is_absent
def test_duplicate_interface_name(self): iface_infos = self._gen_iface_infos() iface_infos.append(deepcopy(iface_infos[0])) with pytest.raises(NmstateValueError): Ifaces(des_iface_infos=iface_infos, cur_iface_infos=[])
def test_state_to_edit_with_empty_desire(self): cur_iface_infos = self._gen_iface_infos() ifaces = Ifaces([], cur_iface_infos) assert ifaces.state_to_edit == []
def test_validate_unknown_slaves(self): cur_iface_infos = self._gen_iface_infos() des_iface_info = gen_bridge_iface_info() with pytest.raises(NmstateValueError): Ifaces([des_iface_info], cur_iface_infos)