def test_intf(mocked_log_warn): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': {}, } m = InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_VLAN_INTF_TABLE_NAME) set_handler_test(m, "Vlan1000", {}) set_handler_test(m, "Vlan1000|192.168.0.1/21", {}) # test set handler with invalid ip network res = m.set_handler("Vlan1000|invalid_netowrk", {}) assert res, "Returns always True" mocked_log_warn.assert_called_with( "Subnet 'invalid_netowrk' format is wrong for interface 'Vlan1000'") del_handler_test(m, "Vlan1000") del_handler_test(m, "Vlan1000|192.168.0.1/21") del_handler_test(m, "Vlan1000|invalid_netowrk") mocked_log_warn.assert_called_with( "Subnet 'invalid_netowrk' format is wrong for interface 'Vlan1000'")
def test_set_del_handler(): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': {}, } m = BGPDataBaseMgr(common_objs, "CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME) assert m.constants == {} # test set_handler res = m.set_handler("test_key1", {"test_value1"}) assert res, "Returns always True" assert "test_key1" in m.directory.get_slot(m.db_name, m.table_name) assert m.directory.get(m.db_name, m.table_name, "test_key1") == {"test_value1"} res = m.set_handler("test_key2", {}) assert res, "Returns always True" assert "test_key2" in m.directory.get_slot(m.db_name, m.table_name) assert m.directory.get(m.db_name, m.table_name, "test_key2") == {} # test del_handler m.del_handler("test_key") assert "test_key" not in m.directory.get_slot(m.db_name, m.table_name) assert "test_key2" in m.directory.get_slot(m.db_name, m.table_name) assert m.directory.get(m.db_name, m.table_name, "test_key2") == {} m.del_handler("test_key2") assert "test_key2" not in m.directory.get_slot(m.db_name, m.table_name)
def parse_instance_conf(filename): activate_re = re.compile(r'^neighbor\s+(\S+)\s+activate$') with open(filename) as fp: lines = [ line.strip() for line in fp if not line.strip().startswith('!') and line.strip() != '' ] # Search all v6 neighbors neighbors = {} for line in lines: if activate_re.match(line): neighbor = activate_re.match(line).group(1) if TemplateFabric.is_ipv6(neighbor): neighbors[neighbor] = {} # Extract peer-groups and route-maps for neighbor, neighbor_data in neighbors.items(): route_map_in_re = re.compile( r'^neighbor\s+%s\s+route-map\s+(\S+) in$' % neighbor) peer_group_re = re.compile(r'^neighbor\s+%s\s+peer-group\s+(\S+)$' % neighbor) for line in lines: if route_map_in_re.match(line): assert "route-map" not in neighbor_data neighbor_data["route-map"] = route_map_in_re.match(line).group( 1) if peer_group_re.match(line): assert "peer-group" not in neighbor_data neighbor_data["peer-group"] = peer_group_re.match(line).group( 1) # Ensure that every ivp6 neighbor has either route-map or peer-group for neighbor, neighbor_data in neighbors.items(): assert "route-map" in neighbor_data or "peer-group" in neighbor_data,\ "IPv6 neighbor '%s' must have either route-map in or peer-group %s" % (neighbor, neighbor_data) return neighbors
def run_tests(test_name, template_fname, tests): tf = TemplateFabric(TEMPLATE_PATH) template = tf.from_file(template_fname) for case_name, param_fname, result_fname in tests: params = load_json(param_fname) raw_generated_result = str(template.render(params)) assert "None" not in raw_generated_result, "Test %s.%s" % (test_name, case_name) # this is used only for initial generation write_result(result_fname, raw_generated_result) canonical_generated_result = ConfigMgr.to_canonical( raw_generated_result) with open(result_fname) as result_fp: raw_saved_result = result_fp.read() canonical_saved_result = ConfigMgr.to_canonical(raw_saved_result) assert canonical_saved_result == canonical_generated_result, "Test %s.%s" % ( test_name, case_name)
def test___restart_peers_found_deployment_id(): from bgpcfgd.managers_allow_list import BGPAllowListMgr test___restart_peers_found_deployment_id.run_command_counter = 0 def run_command(cmd): output = [ ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_1 soft in'], ['vtysh', '-c', 'clear bgp peer-group BGP_TEST_PEER_GROUP_2 soft in'], ] desired_value = output[test___restart_peers_found_deployment_id.run_command_counter] assert cmd == desired_value test___restart_peers_found_deployment_id.run_command_counter += 1 return 0, "", "" cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': global_constants, } mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') mocked.return_value = ["BGP_TEST_PEER_GROUP_1", "BGP_TEST_PEER_GROUP_2"] mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked bgpcfgd.managers_allow_list.run_command = run_command rc = mgr._BGPAllowListMgr__restart_peers(5) assert rc
def set_del_test(op, args, currect_config, expected_config): from bgpcfgd.managers_allow_list import BGPAllowListMgr set_del_test.push_list_called = False def push_list(args): set_del_test.push_list_called = True assert args == expected_config return True # bgpcfgd.frr.run_command = lambda cmd: (0, "", "") # cfg_mgr = MagicMock() cfg_mgr.update.return_value = None cfg_mgr.push_list = push_list cfg_mgr.get_text.return_value = currect_config common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': global_constants, } mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") if op == "SET": mgr.set_handler(*args) elif op == "DEL": mgr.del_handler(*args) else: assert False, "Wrong operation" if expected_config: assert set_del_test.push_list_called, "cfg_mgr.push_list wasn't called" else: assert not set_del_test.push_list_called, "cfg_mgr.push_list was called"
def test__get_available_peer_groups(): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': global_constants, } m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") m.cfg_mgr.get_text = MagicMock(return_value=[ ' neighbor PEER_V4 peer-group', ' neighbor PEER_V6 peer-group', ' address-family ipv4', ' neighbor PEER_V4 allowas-in 1', ' neighbor PEER_V4 soft-reconfiguration inbound', ' neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in', ' neighbor PEER_V4 route-map TO_BGP_PEER_V4 out', ' exit-address-family', ' address-family ipv6', ' neighbor PEER_V6 allowas-in 1', ' neighbor PEER_V6 soft-reconfiguration inbound', ' neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in', ' neighbor PEER_V6 route-map TO_BGP_PEER_V6 out', ' exit-address-family', ' ', ]) res = m._BBRMgr__get_available_peer_groups() assert res == {"PEER_V4", "PEER_V6"}
def __restart_peers_common(run_command_results, run_command_expects, last_log_crit_message, mocked_log_crit): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': global_constants, } m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") m.bbr_enabled_pgs = { "PEER_V4": ["ipv4", "ipv6"], "PEER_V6": ["ipv6"], } def run_command_mock(cmd): assert cmd == run_command_expects[run_command_mock.run] res = run_command_results[run_command_mock.run] run_command_mock.run += 1 return res run_command_mock.run = 0 bgpcfgd.managers_bbr.run_command = run_command_mock #lambda cmd: (0, "", "") m._BBRMgr__restart_peers() if last_log_crit_message is not None: mocked_log_crit.assert_called_with(last_log_crit_message)
def test___set_handler_validate(): from bgpcfgd.managers_allow_list import BGPAllowListMgr cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': global_constants, } mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") data = { "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", "prefixes_v6": "fc01:20::/64,fc01:30::/64", } assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", None) assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID1|5|1010:2020", data) assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|z|1010:2020", data) assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", "prefixes_v6": "20.20.30.0/24,40.50.0.0/16", }) assert not mgr._BGPAllowListMgr__set_handler_validate("DEPLOYMENT_ID|5|1010:2020", { "prefixes_v4": "fc01:20::/64,fc01:30::/64", "prefixes_v6": "fc01:20::/64,fc01:30::/64", })
def __set_prepare_config_common(status, bbr_enabled_pgs, available_pgs, mapping_pgs, expected_cmds, bbr_applied_pgs=None): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': global_constants, } m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") m.directory.data = { "CONFIG_DB__DEVICE_METADATA": { "localhost": { "bgp_asn": "65500" } } } m.bbr_enabled_pgs = bbr_enabled_pgs m._BBRMgr__get_available_peer_groups = MagicMock( return_value=available_pgs) m._BBRMgr__get_available_peers_per_peer_group = MagicMock( return_value=mapping_pgs) cmds, peer_groups = m._BBRMgr__set_prepare_config(status) assert cmds == expected_cmds assert set(peer_groups) == (available_pgs if not bbr_applied_pgs else bbr_applied_pgs)
def test_set_handler_no_community_data_is_already_presented(): from bgpcfgd.managers_allow_list import BGPAllowListMgr cfg_mgr = MagicMock() cfg_mgr.update.return_value = None cfg_mgr.get_text.return_value = [ 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17', 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 le 32', 'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 le 32', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 le 128', 'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 le 128', 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000', ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4', 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000', ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6', 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 65535', ' set community 123:123 additive', 'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 65535', ' set community 123:123 additive', "" ] common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': global_constants, } mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") mgr.set_handler("DEPLOYMENT_ID|5", { "prefixes_v4": "20.20.30.0/24,40.50.0.0/16", "prefixes_v6": "fc01:20::/64,fc01:30::/64", }) assert not cfg_mgr.push_list.called, "cfg_mgr.push_list was called, but it shouldn't have been"
def test_pfx_filter_wrong_ip(caplog): src = { ('Loopback0', 'wrong_ip'): {}, } res = TemplateFabric.pfx_filter(src) assert "'wrong_ip' is invalid ip address" in caplog.text assert isinstance(res, OrderedDict) and len(res) == 0
def test_pfx_filter_strings(): src = { 'Loopback0': {}, 'Loopback1': {}, } expected = OrderedDict([]) res = TemplateFabric.pfx_filter(src) assert res == expected
def construct_BGPAllowListMgr(constants): from bgpcfgd.managers_allow_list import BGPAllowListMgr cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': constants, } mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") return mgr
def test_pfx_filter_pfx_v6_no_mask(): src = { ('Loopback0', 'fc00::'): {}, ('Loopback1', 'fc00::1'): {}, } expected = OrderedDict([ (('Loopback0', 'fc00::/128'), {}), (('Loopback1', 'fc00::1/128'), {}), ]) res = TemplateFabric.pfx_filter(src) assert res == expected
def test_pfx_filter_pfx_v4_no_mask(): src = { ('Loopback0', '11.11.11.11'): {}, ('Loopback1', '55.55.55.55'): {}, } expected = OrderedDict([ (('Loopback1', '55.55.55.55/32'), {}), (('Loopback0', '11.11.11.11/32'), {}), ]) res = TemplateFabric.pfx_filter(src) assert dict(res) == dict(expected)
def test_constructor(): #m1, m2, m3): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': {}, } m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") assert not m.enabled assert len(m.bbr_enabled_pgs) == 0 assert m.directory.get("CONFIG_DB", "BGP_BBR", "status") == "disabled"
def test_del_handler(mocked_log_err): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': global_constants, } m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") m.del_handler("anything") mocked_log_err.assert_called_with( "The 'BGP_BBR' table shouldn't be removed from the db")
def test_intf_ipv6(): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': {}, } m = InterfaceMgr(common_objs, "CONFIG_DB", swsscommon.CFG_VLAN_INTF_TABLE_NAME) set_handler_test(m, "Vlan1000|fc02:1000::1/64", {}) del_handler_test(m, "Vlan1000|fc02:1000::1/64")
def test_pfx_filter_mixed_keys(): src = { 'Loopback0': {}, ('Loopback0', '11.11.11.11/32'): {}, 'Loopback1': {}, ('Loopback1', '55.55.55.55/32'): {}, } expected = OrderedDict([ (('Loopback1', '55.55.55.55/32'), {}), (('Loopback0', '11.11.11.11/32'), {}), ]) res = TemplateFabric.pfx_filter(src) assert dict(res) == dict(expected)
def read_pgs_common(constants, expected_log_info, expected_bbr_enabled_pgs, mocked_log_info): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': constants, } m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") res = m._BBRMgr__read_pgs() assert res == expected_bbr_enabled_pgs if expected_log_info is not None: mocked_log_info.assert_called_with(expected_log_info)
def constructor(): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': {}, } mgr = StaticRouteMgr(common_objs, "CONFIG_DB", "STATIC_ROUTE") assert len(mgr.static_routes) == 0 return mgr
def __set_validation_common(key, data, expected_log_err, expected_result, mocked_log_err): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': global_constants, } m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") res = m._BBRMgr__set_validation(key, data) assert res == expected_result if expected_log_err is not None: mocked_log_err.assert_called_with(expected_log_err)
def constructor(): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(TEMPLATE_PATH), 'constants': {}, } m = ZebraSetSrc(common_objs, "STATE_DB", swsscommon.STATE_INTERFACE_TABLE_NAME) assert m.lo_ipv4 == None assert m.lo_ipv6 == None return m
def test___to_prefix_list(): from bgpcfgd.managers_allow_list import BGPAllowListMgr cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': global_constants, } mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") res_v4 = mgr._BGPAllowListMgr__to_prefix_list(mgr.V4, ["1.2.3.4/32", "10.20.20.10/24"]) assert res_v4 == ["permit 1.2.3.4/32", "permit 10.20.20.10/24 le 32"] res_v6 = mgr._BGPAllowListMgr__to_prefix_list(mgr.V6, ["fc00::1/128", "fc00::/64"]) assert res_v6 == ["permit fc00::1/128", "permit fc00::/64 le 128"]
def constructor(skip_bgp_asn=False): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': {}, } mgr = StaticRouteMgr(common_objs, "CONFIG_DB", "STATIC_ROUTE") if not skip_bgp_asn: mgr.directory.put("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost", {"bgp_asn": "65100"}) assert len(mgr.static_routes) == 0 return mgr
def constructor(skip_bgp_asn=False): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': {}, } mgr = AdvertiseRouteMgr(common_objs, "STATE_DB", swsscommon.STATE_ADVERTISE_NETWORK_TABLE_NAME) if not skip_bgp_asn: mgr.directory.put("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost", {"bgp_asn": "65100"}) assert len(mgr.advertised_routes) == 0 return mgr
def test___restart_peers_not_found_deployment_id(): from bgpcfgd.managers_allow_list import BGPAllowListMgr def run_command(cmd): assert cmd == ['vtysh', '-c', 'clear bgp * soft in'] return 0, "", "" cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': global_constants, } mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES") mocked = MagicMock(name='_BGPAllowListMgr__find_peer_group_by_deployment_id') mocked.return_value = [] mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked bgpcfgd.managers_allow_list.run_command = run_command rc = mgr._BGPAllowListMgr__restart_peers(5) assert rc
def __set_prepare_config_common(status, bbr_enabled_pgs, expected_cmds): cfg_mgr = MagicMock() common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(), 'constants': global_constants, } m = BBRMgr(common_objs, "CONFIG_DB", "BGP_BBR") m.directory.data = { "CONFIG_DB__DEVICE_METADATA": { "localhost": { "bgp_asn": "65500" } } } m.bbr_enabled_pgs = bbr_enabled_pgs cmds = m._BBRMgr__set_prepare_config(status) assert cmds == expected_cmds
def constructor(): cfg_mgr = MagicMock() constants = load_constants()['constants'] common_objs = { 'directory': Directory(), 'cfg_mgr': cfg_mgr, 'tf': TemplateFabric(TEMPLATE_PATH), 'constants': constants } return_value_map = { "['vtysh', '-c', 'show bgp vrfs json']": (0, "{\"vrfs\": {\"default\": {}}}", ""), "['vtysh', '-c', 'show bgp vrf default neighbors json']": (0, "{\"10.10.10.1\": {}, \"20.20.20.1\": {}, \"fc00:10::1\": {}}", "") } bgpcfgd.managers_bgp.run_command = lambda cmd: return_value_map[str(cmd)] m = bgpcfgd.managers_bgp.BGPPeerMgrBase( common_objs, "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME, "general", True) assert m.peer_type == "general" assert m.check_neig_meta == ('bgp' in constants and 'use_neighbors_meta' in constants['bgp'] and constants['bgp']['use_neighbors_meta']) m.directory.put("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost", {"bgp_asn": "65100"}) m.directory.put("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME, "Loopback0|11.11.11.11/32", {}) m.directory.put("CONFIG_DB", swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME, "Loopback0|FC00:1::32/128", {}) m.directory.put("LOCAL", "local_addresses", "30.30.30.30", {"interface": "Ethernet4|30.30.30.30/24"}) m.directory.put("LOCAL", "local_addresses", "fc00:20::20", {"interface": "Ethernet8|fc00:20::20/96"}) m.directory.put("LOCAL", "interfaces", "Ethernet4|30.30.30.30/24", {"anything": "anything"}) m.directory.put("LOCAL", "interfaces", "Ethernet8|fc00:20::20/96", {"anything": "anything"}) return m