Skip to content

Commit 11e374e

Browse files
add VS test for PL
Signed-off-by: Lawrence Lee <[email protected]>
1 parent 1a7685d commit 11e374e

File tree

4 files changed

+328
-48
lines changed

4 files changed

+328
-48
lines changed

tests/dash_utils.py

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
from swsscommon import swsscommon
2+
import typing
3+
import pytest
4+
5+
@pytest.fixture(scope='module')
6+
def dash_db(dvs):
7+
return DashDB(dvs)
8+
9+
def to_string(value):
10+
if isinstance(value, bool):
11+
return "true" if value else "false"
12+
elif isinstance(value, bytes):
13+
return value
14+
return str(value)
15+
16+
class ProducerStateTable(swsscommon.ProducerStateTable):
17+
def __setitem__(self, key: str, pairs: typing.Union[dict, list, tuple]):
18+
pairs_str = []
19+
if isinstance(pairs, dict):
20+
pairs = pairs.items()
21+
for k, v in pairs:
22+
pairs_str.append((to_string(k), to_string(v)))
23+
self.set(key, pairs_str)
24+
25+
def __delitem__(self, key: str):
26+
self.delete(str(key))
27+
28+
29+
class Table(swsscommon.Table):
30+
def __getitem__(self, key: str):
31+
exists, result = self.get(str(key))
32+
if not exists:
33+
return None
34+
else:
35+
return dict(result)
36+
37+
def get_keys(self):
38+
return self.getKeys()
39+
40+
def get_newly_created_oid(self, old_oids):
41+
new_oids = self.asic_db.wait_for_n_keys(self, len(old_oids) + 1)
42+
oid = [ids for ids in new_oids if ids not in old_oids]
43+
return oid[0]
44+
45+
46+
class DashDB(object):
47+
def __init__(self, dvs):
48+
self.dvs = dvs
49+
self.app_dash_routing_type_table = ProducerStateTable(
50+
self.dvs.get_app_db().db_connection, "DASH_ROUTING_TYPE_TABLE")
51+
self.app_dash_appliance_table = ProducerStateTable(
52+
self.dvs.get_app_db().db_connection, "DASH_APPLIANCE_TABLE")
53+
self.asic_direction_lookup_table = Table(
54+
self.dvs.get_asic_db().db_connection, "ASIC_STATE:SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY")
55+
self.asic_vip_table = Table(
56+
self.dvs.get_asic_db().db_connection, "ASIC_STATE:SAI_OBJECT_TYPE_VIP_ENTRY")
57+
self.app_dash_vnet_table = ProducerStateTable(
58+
self.dvs.get_app_db().db_connection, "DASH_VNET_TABLE")
59+
self.asic_dash_vnet_table = Table(
60+
self.dvs.get_asic_db().db_connection, "ASIC_STATE:SAI_OBJECT_TYPE_VNET")
61+
self.app_dash_eni_table = ProducerStateTable(
62+
self.dvs.get_app_db().db_connection, "DASH_ENI_TABLE")
63+
self.asic_eni_table = Table(
64+
self.dvs.get_asic_db().db_connection, "ASIC_STATE:SAI_OBJECT_TYPE_ENI")
65+
self.asic_eni_ether_addr_map_table = Table(
66+
self.dvs.get_asic_db().db_connection, "ASIC_STATE:SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY")
67+
self.app_dash_vnet_map_table = ProducerStateTable(
68+
self.dvs.get_app_db().db_connection, "DASH_VNET_MAPPING_TABLE")
69+
self.asic_dash_outbound_ca_to_pa_table = Table(
70+
self.dvs.get_asic_db().db_connection, "ASIC_STATE:SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY")
71+
self.asic_pa_validation_table = Table(
72+
self.dvs.get_asic_db().db_connection, "ASIC_STATE:SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY")
73+
self.app_dash_route_table = ProducerStateTable(
74+
self.dvs.get_app_db().db_connection, "DASH_ROUTE_TABLE")
75+
self.app_dash_route_rule_table = ProducerStateTable(
76+
self.dvs.get_app_db().db_connection, "DASH_ROUTE_RULE_TABLE")
77+
self.asic_outbound_routing_table = Table(
78+
self.dvs.get_asic_db().db_connection, "ASIC_STATE:SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY")
79+
self.asic_inbound_routing_rule_table = Table(
80+
self.dvs.get_asic_db().db_connection, "ASIC_STATE:SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY")
81+
82+
def create_appliance(self, appliance_id, attr_maps: dict):
83+
self.app_dash_appliance_table[str(appliance_id)] = attr_maps
84+
85+
def remove_appliance(self, appliance_id):
86+
del self.app_dash_appliance_table[str(appliance_id)]
87+
88+
def create_vnet(self, vnet, attr_maps: dict):
89+
self.app_dash_vnet_table[str(vnet)] = attr_maps
90+
91+
def remove_vnet(self, vnet):
92+
del self.app_dash_vnet_table[str(vnet)]
93+
94+
def create_eni(self, eni, attr_maps: dict):
95+
self.app_dash_eni_table[str(eni)] = attr_maps
96+
97+
def remove_eni(self, eni):
98+
del self.app_dash_eni_table[str(eni)]
99+
100+
def create_vnet_map(self, vnet, ip, attr_maps: dict):
101+
self.app_dash_vnet_map_table[str(vnet) + ":" + str(ip)] = attr_maps
102+
103+
def remove_vnet_map(self, vnet, ip):
104+
del self.app_dash_vnet_map_table[str(vnet) + ":" + str(ip)]
105+
106+
def create_outbound_routing(self, mac_string, ip, attr_maps: dict):
107+
self.app_dash_route_table[str(mac_string) + ":" + str(ip)] = attr_maps
108+
109+
def remove_outbound_routing(self, mac_string, ip):
110+
del self.app_dash_route_table[str(mac_string) + ":" + str(ip)]
111+
112+
def create_inbound_routing(self, mac_string, vni, ip, attr_maps: dict):
113+
self.app_dash_route_rule_table[str(mac_string) + ":" + str(vni) + ":" + str(ip)] = attr_maps
114+
115+
def remove_inbound_routing(self, mac_string, vni, ip):
116+
del self.app_dash_route_rule_table[str(mac_string) + ":" + str(vni) + ":" + str(ip)]
117+
118+
def create_routing_type(self, routing_type, attr_maps: dict):
119+
self.app_dash_routing_type_table[str(routing_type)] = attr_maps
120+
121+
def remove_routing_type(self, routing_type):
122+
del self.app_dash_routing_type_table[str(routing_type)]

tests/sai_attrs.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
SAI_ENI_ATTR_PL_SIP = 'SAI_ENI_ATTR_PL_SIP'
2+
SAI_ENI_ATTR_PL_SIP_MASK = 'SAI_ENI_ATTR_PL_SIP_MASK'
3+
SAI_ENI_ATTR_PL_UNDERLAY_SIP = 'SAI_ENI_ATTR_PL_UNDERLAY_SIP'
4+
SAI_OUTBOUND_CA_TO_PA_ENTRY_ACTION_SET_TUNNEL_MAPPING = 'SAI_OUTBOUND_CA_TO_PA_ENTRY_ACTION_SET_TUNNEL_MAPPING'
5+
SAI_OUTBOUND_CA_TO_PA_ENTRY_ACTION_SET_PRIVATE_LINK_MAPPING = 'SAI_OUTBOUND_CA_TO_PA_ENTRY_ACTION_SET_PRIVATE_LINK_MAPPING'
6+
SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_ACTION = 'SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_ACTION'
7+
SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_SIP = 'SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_SIP'
8+
SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DIP = 'SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DIP'
9+
SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_DASH_ENCAPSULATION = 'SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_DASH_ENCAPSULATION'
10+
SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_TUNNEL_KEY = 'SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_TUNNEL_KEY'
11+
SAI_DASH_ENCAPSULATION_NVGRE = 'SAI_DASH_ENCAPSULATION_NVGRE'

tests/test_dash_pl.py

+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import base64
2+
import socket
3+
import pytest
4+
import time
5+
import uuid
6+
7+
from ipaddress import ip_address as IP
8+
9+
from dash_api.appliance_pb2 import *
10+
from dash_api.vnet_pb2 import *
11+
from dash_api.eni_pb2 import *
12+
from dash_api.route_pb2 import *
13+
from dash_api.route_rule_pb2 import *
14+
from dash_api.vnet_mapping_pb2 import *
15+
from dash_api.route_type_pb2 import *
16+
from dash_api.types_pb2 import *
17+
from google.protobuf.json_format import ParseDict, MessageToDict
18+
19+
from dash_utils import dash_db
20+
from sai_attrs import *
21+
22+
DVS_ENV = ["HWSKU=DPU-2P"]
23+
NUM_PORTS = 2
24+
25+
APPLIANCE = {
26+
"sip": {
27+
"ipv4": socket.htonl(int(IP("10.0.0.1")))
28+
},
29+
"vm_vni": 4321
30+
}
31+
32+
VNET = {
33+
"vni": "45654",
34+
"guid": {
35+
"value": base64.b64encode(bytes.fromhex(uuid.UUID("559c6ce8-26ab-4193-b946-ccc6e8f930b2").hex))
36+
}
37+
}
38+
39+
PL_ENCODING_IP = "2001:0:20::"
40+
PL_ENCODING_MASK = "::ffff:ffff"
41+
PL_UNDERLAY_SIP = "55.1.2.3"
42+
43+
ENI = {
44+
"vnet": "Vnet1",
45+
"underlay_ip": {
46+
"ipv4": socket.htonl(int(IP("25.1.1.1")))
47+
},
48+
"mac_address": bytes.fromhex("F4939FEFC47E"),
49+
"eni_id": "497f23d7-f0ac-4c99-a98f-59b470e8c7bd",
50+
"admin_state": State.STATE_ENABLED,
51+
"pl_underlay_sip": {
52+
"ipv4": socket.htonl(int(IP(PL_UNDERLAY_SIP)))
53+
},
54+
"pl_sip_encoding": {
55+
"ip": {
56+
"ipv6": base64.b64encode(IP(PL_ENCODING_IP).packed)
57+
},
58+
"mask": {
59+
"ipv6": base64.b64encode(IP(PL_ENCODING_MASK).packed)
60+
}
61+
}
62+
}
63+
64+
PL_OVERLAY_SIP = "fd40:108:0:d204:0:200::0"
65+
PL_OVERLAY_DIP = "2603:10e1:100:2::3401:203"
66+
VNET_MAPPING = {
67+
"mac_address": bytes.fromhex("F4939FEFC47E"),
68+
"action_type": RoutingType.ROUTING_TYPE_PRIVATELINK,
69+
"underlay_ip": {
70+
"ipv4": socket.htonl(int(IP("101.1.2.3")))
71+
},
72+
"overlay_sip": {
73+
"ipv6": base64.b64encode(IP(PL_OVERLAY_SIP).packed)
74+
},
75+
"overlay_dip": {
76+
"ipv6": base64.b64encode(IP(PL_OVERLAY_DIP).packed)
77+
},
78+
}
79+
80+
ROUTE = {
81+
"action_type": RoutingType.ROUTING_TYPE_VNET,
82+
"vnet": "Vnet1",
83+
}
84+
85+
ENCAP_VNI = 100
86+
ROUTING_TYPE = {
87+
"items": [
88+
{
89+
"action_name": "action1",
90+
"action_type": ActionType.ACTION_TYPE_4_to_6
91+
},
92+
{
93+
"action_name": "action2",
94+
"action_type": ActionType.ACTION_TYPE_STATICENCAP,
95+
"encap_type": EncapType.ENCAP_TYPE_NVGRE,
96+
"vni": ENCAP_VNI
97+
}
98+
]
99+
}
100+
101+
@pytest.fixture(scope='module', autouse=True)
102+
def common_setup_teardown(dash_db):
103+
pb = Vnet()
104+
pb.vni = int("45654")
105+
pb.guid.value = bytes.fromhex(uuid.UUID("559c6ce8-26ab-4193-b946-ccc6e8f930b2").hex)
106+
appliance_id = "100"
107+
appliance_msg = ParseDict(APPLIANCE, Appliance())
108+
dash_db.create_appliance(appliance_id, {"pb": appliance_msg.SerializeToString()})
109+
vnet_msg = ParseDict(VNET, Vnet())
110+
vnet = "Vnet1"
111+
dash_db.create_vnet(vnet, {"pb": vnet_msg.SerializeToString()})
112+
eni_msg = ParseDict(ENI, Eni())
113+
eni = "F4939FEFC47E"
114+
dash_db.create_eni(eni, {"pb": eni_msg.SerializeToString()})
115+
routing_type_msg = ParseDict(ROUTING_TYPE, RouteType())
116+
dash_db.create_routing_type("privatelink", {"pb": routing_type_msg.SerializeToString()})
117+
vnet_mapping_msg = ParseDict(VNET_MAPPING, VnetMapping())
118+
vnet_map_ip = "10.1.1.1"
119+
dash_db.create_vnet_map(vnet, vnet_map_ip, {"pb": vnet_mapping_msg.SerializeToString()})
120+
route_msg = ParseDict(ROUTE, Route())
121+
route_prefix = "10.1.0.8/32"
122+
dash_db.create_outbound_routing(eni, route_prefix, {"pb": route_msg.SerializeToString()})
123+
124+
time.sleep(3)
125+
126+
def test_pl_eni_attrs(dash_db):
127+
enis = dash_db.asic_eni_table.get_keys()
128+
assert enis
129+
eni_attrs = dash_db.asic_eni_table[enis[0]]
130+
assert SAI_ENI_ATTR_PL_SIP in eni_attrs
131+
assert eni_attrs[SAI_ENI_ATTR_PL_SIP] == PL_ENCODING_IP
132+
assert SAI_ENI_ATTR_PL_SIP_MASK in eni_attrs
133+
actual_mask = IP(eni_attrs[SAI_ENI_ATTR_PL_SIP_MASK])
134+
assert actual_mask == IP(PL_ENCODING_MASK)
135+
assert SAI_ENI_ATTR_PL_UNDERLAY_SIP in eni_attrs
136+
assert eni_attrs[SAI_ENI_ATTR_PL_UNDERLAY_SIP] == PL_UNDERLAY_SIP
137+
138+
def test_pl_outbound_ca_to_pa_attrs(dash_db):
139+
outbound_ca_to_pa_keys = dash_db.asic_dash_outbound_ca_to_pa_table.get_keys()
140+
assert outbound_ca_to_pa_keys
141+
outbound_attrs = dash_db.asic_dash_outbound_ca_to_pa_table[outbound_ca_to_pa_keys[0]]
142+
143+
assert SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_ACTION in outbound_attrs
144+
assert outbound_attrs[SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_ACTION] == SAI_OUTBOUND_CA_TO_PA_ENTRY_ACTION_SET_PRIVATE_LINK_MAPPING
145+
assert SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_SIP in outbound_attrs
146+
actual_overlay_sip = IP(outbound_attrs[SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_SIP])
147+
assert actual_overlay_sip == IP(PL_OVERLAY_SIP)
148+
assert SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DIP in outbound_attrs
149+
actual_overlay_dip = IP(outbound_attrs[SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DIP])
150+
assert actual_overlay_dip == IP(PL_OVERLAY_DIP)
151+
assert SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_TUNNEL_KEY in outbound_attrs
152+
assert int(outbound_attrs[SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_TUNNEL_KEY]) == ENCAP_VNI
153+
assert SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_DASH_ENCAPSULATION in outbound_attrs
154+
assert outbound_attrs[SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_DASH_ENCAPSULATION] == SAI_DASH_ENCAPSULATION_NVGRE

0 commit comments

Comments
 (0)