blob: 1b4b88efc48c937cc5daedb813b747fba85002a8 [file] [log] [blame]
Daniele Moro790cc102021-08-30 18:27:30 +02001class UP4:
2
3 def __init__(self):
4 self.default = ''
5
Daniele Moro790cc102021-08-30 18:27:30 +02006 def CASE1(self, main):
Daniele Morobf53dec2021-09-13 18:11:56 +02007 main.case("Fabric UPF traffic terminated in the fabric")
Daniele Moro790cc102021-08-30 18:27:30 +02008 """
Daniele Moro49a843c2022-01-05 14:36:32 +01009 Program UPF entities for UEs
10 Verify UPF entities
Daniele Moro790cc102021-08-30 18:27:30 +020011 Generate traffic from UE to PDN
12 Verify traffic received from PDN
13 Generate traffic from PDN to UE
14 Verify traffic received from UE
Daniele Moro49a843c2022-01-05 14:36:32 +010015 Remove UPF entities for UEs
16 Verify removed UPF entities
Daniele Moro790cc102021-08-30 18:27:30 +020017 """
Daniele Moro790cc102021-08-30 18:27:30 +020018 try:
Daniele Moro54581242022-02-25 19:56:02 +010019 from tests.USECASE.SegmentRouting.dependencies.up4 import UP4
Daniele Moro790cc102021-08-30 18:27:30 +020020 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import \
21 Testcaselib as run
Daniele Moro790cc102021-08-30 18:27:30 +020022 except ImportError as e:
23 main.log.error("Import not found. Exiting the test")
24 main.log.error(e)
25 main.cleanAndExit()
Daniele Moroc6811a82021-10-12 11:29:41 +020026 n_switches = int(main.params["TOPO"]["switchNum"])
Daniele Moro790cc102021-08-30 18:27:30 +020027
Daniele Moro790cc102021-08-30 18:27:30 +020028 run.initTest(main)
29 main.log.info(main.Cluster.numCtrls)
30 main.Cluster.setRunningNode(3)
31 run.installOnos(main, skipPackage=True, cliSleep=5)
32
Daniele Moro790cc102021-08-30 18:27:30 +020033 main.step("Start scapy and p4rt client")
Daniele Morobf53dec2021-09-13 18:11:56 +020034 # Use the first available ONOS instance CLI
35 onos_cli = main.Cluster.active(0).CLI
Daniele Moro80889562021-09-08 10:09:26 +020036 up4 = UP4()
37 # Get the P4RT client connected to UP4 in the first available ONOS instance
38 up4.setup(main.Cluster.active(0).p4rtUp4)
Daniele Moro790cc102021-08-30 18:27:30 +020039
Daniele Moro49a843c2022-01-05 14:36:32 +010040 main.step("Program and Verify UPF entities via UP4")
Daniele Moro80889562021-09-08 10:09:26 +020041 up4.attachUes()
Daniele Morobf53dec2021-09-13 18:11:56 +020042 up4.verifyUp4Flow(onos_cli)
43
Daniele Moro80889562021-09-08 10:09:26 +020044 # ------- Test Upstream traffic (enb->pdn)
Daniele Morobef0c7e2022-02-16 17:47:13 -080045 for app_filter_name in up4.app_filters:
46 main.step("Test upstream traffic %s" % app_filter_name)
47 up4.testUpstreamTraffic(app_filter_name=app_filter_name)
Daniele Moro790cc102021-08-30 18:27:30 +020048
Daniele Moro80889562021-09-08 10:09:26 +020049 # ------- Test Downstream traffic (pdn->enb)
Daniele Morobef0c7e2022-02-16 17:47:13 -080050 for app_filter_name in up4.app_filters:
51 main.step("Test downstream traffic %s" % app_filter_name)
52 up4.testDownstreamTraffic(app_filter_name=app_filter_name)
Daniele Moro790cc102021-08-30 18:27:30 +020053
Daniele Moro49a843c2022-01-05 14:36:32 +010054 main.step("Remove and Verify UPF entities via UP4")
Daniele Moro80889562021-09-08 10:09:26 +020055 up4.detachUes()
Daniele Morobf53dec2021-09-13 18:11:56 +020056 up4.verifyNoUesFlow(onos_cli)
57
Daniele Moro790cc102021-08-30 18:27:30 +020058 main.step("Stop scapy and p4rt client")
Daniele Moro80889562021-09-08 10:09:26 +020059 up4.teardown()
Daniele Moroc99bf822021-10-11 23:21:15 +020060
Daniele Moro790cc102021-08-30 18:27:30 +020061 run.cleanup(main)
Daniele Morobf53dec2021-09-13 18:11:56 +020062
Daniele Moro9ba5cf02021-10-08 18:00:56 +020063 def CASE2(self, main):
Daniele Morobf53dec2021-09-13 18:11:56 +020064 main.case("BESS traffic routed")
65 """
Daniele Moro49a843c2022-01-05 14:36:32 +010066 Program UPF entities for UEs managed via UP4
67 Verify UPF entities
Daniele Morobf53dec2021-09-13 18:11:56 +020068 Verify Upstream Traffic: eNB -> Fabric -> BESS (encapped)
69 Verify Upstream Traffic: BESS -> Fabric -> PDN (not encapped)
70 Verify Downstream Traffic: PDN -> Fabric -> BESS (not encapped)
71 Verify Downstream Traffic: BESS -> Fabric -> eNB (encapped)
Daniele Moro49a843c2022-01-05 14:36:32 +010072 Remove UPF entities for UEs managed via UP4
73 Verify removed UPF entities
Daniele Morobf53dec2021-09-13 18:11:56 +020074 """
75 BESS_TEID = 300
Daniele Morobf53dec2021-09-13 18:11:56 +020076 GPDU_PORT = 2152
77 UE_PORT = 400
78 PDN_PORT = 800
79 try:
Daniele Moro54581242022-02-25 19:56:02 +010080 from tests.USECASE.SegmentRouting.dependencies.up4 import UP4
Daniele Morobf53dec2021-09-13 18:11:56 +020081 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import \
82 Testcaselib as run
83 except ImportError as e:
84 main.log.error("Import not found. Exiting the test")
85 main.log.error(e)
86 main.cleanAndExit()
Daniele Moroc6811a82021-10-12 11:29:41 +020087 n_switches = int(main.params["TOPO"]["switchNum"])
Daniele Morobf53dec2021-09-13 18:11:56 +020088
89 run.initTest(main)
90 main.log.info(main.Cluster.numCtrls)
91 main.Cluster.setRunningNode(3)
92 run.installOnos(main, skipPackage=True, cliSleep=5)
93
94 main.step("Start scapy and p4rt client + Scapy on BESS Host")
95 # Use the first available ONOS instance CLI
96 onos_cli = main.Cluster.active(0).CLI
97 up4 = UP4()
98 # Get the P4RT client connected to UP4 in the first available ONOS instance
99 up4.setup(main.Cluster.active(0).p4rtUp4)
100
101 # Setup the emulated BESS host and required parameters
Daniele Moro522023c2021-10-15 17:30:33 +0200102 bess_host = getattr(main, main.params["BESS_UPF"]["bess_host"])
Daniele Morobf53dec2021-09-13 18:11:56 +0200103 bess_interface = bess_host.interfaces[0]
104 bess_s1u_address = bess_interface["ips"][0]
105 bess_host.startScapy(ifaceName=bess_interface["name"], enableGtp=True)
Daniele Moro522023c2021-10-15 17:30:33 +0200106 bess_ue_address = main.params["BESS_UPF"]["ue_address"]
107 enodeb_host = getattr(main, main.params["BESS_UPF"]["enodeb_host"])
108 enodeb_address = main.params["BESS_UPF"]["enb_address"]
109 enodeb_interface = enodeb_host.interfaces[0]["name"]
Daniele Morobf53dec2021-09-13 18:11:56 +0200110 pdn_host = up4.pdn_host
111 pdn_interface = up4.pdn_interface
112
Daniele Moro49a843c2022-01-05 14:36:32 +0100113 main.step("Program and Verify UPF entities for UEs via UP4")
Daniele Morobf53dec2021-09-13 18:11:56 +0200114 up4.attachUes()
Daniele Morobf53dec2021-09-13 18:11:56 +0200115 up4.verifyUp4Flow(onos_cli)
116
117 # ------------------- UPSTREAM -------------------
118 # ------- eNB -> fabric -> BESS (encapped)
119 main.step("Test upstream eNB -> fabric -> BESS")
120 # Start filter before sending packets, BESS should receive GTP encapped
121 # packets
122 pkt_filter_upstream = "ip and udp src port %d and udp dst port %d and src host %s and dst host %s" % (
Daniele Moro522023c2021-10-15 17:30:33 +0200123 GPDU_PORT, GPDU_PORT, enodeb_address, bess_s1u_address)
Daniele Morobf53dec2021-09-13 18:11:56 +0200124 main.log.info("Start listening on %s intf %s" % (
125 bess_host.name, bess_interface["name"]))
126 main.log.debug("BPF Filter BESS Upstream: \n %s" % pkt_filter_upstream)
127 bess_host.startFilter(ifaceName=bess_interface["name"],
128 sniffCount=1,
129 pktFilter=pkt_filter_upstream)
130 # Send GTP Packet
131 UP4.buildGtpPacket(enodeb_host,
Daniele Moro522023c2021-10-15 17:30:33 +0200132 src_ip_outer=enodeb_address,
Daniele Morobf53dec2021-09-13 18:11:56 +0200133 dst_ip_outer=bess_s1u_address,
Daniele Moro522023c2021-10-15 17:30:33 +0200134 src_ip_inner=bess_ue_address,
Daniele Morobf53dec2021-09-13 18:11:56 +0200135 dst_ip_inner=pdn_interface["ips"][0],
136 src_udp_inner=UE_PORT,
137 dst_udp_inner=PDN_PORT,
138 teid=BESS_TEID)
139 enodeb_host.sendPacket()
140
141 packets = UP4.checkFilterAndGetPackets(bess_host)
142 # FIXME: with newer scapy TEID becomes teid (required for Scapy 2.4.5)
143 n_packets = packets.count("TEID=" + hex(BESS_TEID) + "L ")
144 tot_packets = packets.count('Ether')
145 utilities.assert_equal(expect=True,
146 actual=n_packets == 1 and tot_packets == 1,
147 onpass="BESS correctly received 1 GTP encapped packet",
148 onfail="ERROR: BESS received %d GTP encapped packets and filter captured %d packets" % (
149 n_packets, tot_packets))
150
151 # ------- BESS -> fabric -> PDN (not-encapped)
152 main.step("Test upstream BESS -> fabric -> PDN")
153 # Start filter before sending packets, PDN should receive non-GTP packet
154 pkt_filter_upstream = "ip and udp src port %d and udp dst port %d and src host %s and dst host %s" % (
Daniele Moro522023c2021-10-15 17:30:33 +0200155 UE_PORT, PDN_PORT, bess_ue_address, pdn_interface["ips"][0])
Daniele Morobf53dec2021-09-13 18:11:56 +0200156 main.log.info("Start listening on %s intf %s" % (
157 pdn_host.name, pdn_interface["name"]))
158 main.log.debug("BPF Filter PDN Upstream: \n %s" % pkt_filter_upstream)
159 pdn_host.startFilter(ifaceName=pdn_interface["name"],
160 sniffCount=1,
161 pktFilter=pkt_filter_upstream)
162 # Send UDP Packet
163 UP4.buildUdpPacket(bess_host,
Daniele Moro522023c2021-10-15 17:30:33 +0200164 src_ip=bess_ue_address,
Daniele Morobf53dec2021-09-13 18:11:56 +0200165 dst_ip=pdn_interface["ips"][0],
166 src_udp=UE_PORT,
167 dst_udp=PDN_PORT)
168 bess_host.sendPacket()
169
170 packets = UP4.checkFilterAndGetPackets(pdn_host)
171 tot_packets = packets.count('Ether')
172 utilities.assert_equal(expect=True,
173 actual=tot_packets == 1,
174 onpass="PDN correctly received 1 packet",
175 onfail="ERROR: PDN received %d packets" % (
176 tot_packets))
177 # ------------------------------------------------
178
179 # ------------------ DOWNSTREAM ------------------
180 # ------- PDN -> fabric -> BESS (not-encapped)
181 main.step("Test downstream PDN -> fabric -> BESS")
182 pkt_filter_downstream = "ip and udp src port %d and udp dst port %d and src host %s and dst host %s" % (
Daniele Moro522023c2021-10-15 17:30:33 +0200183 PDN_PORT, UE_PORT, pdn_interface["ips"][0], bess_ue_address)
Daniele Morobf53dec2021-09-13 18:11:56 +0200184 main.log.info("Start listening on %s intf %s" % (
185 bess_host.name, bess_interface["name"]))
186 main.log.debug(
187 "BPF Filter BESS Downstream: \n %s" % pkt_filter_downstream)
188 bess_host.startFilter(ifaceName=bess_interface["name"],
189 sniffCount=1,
190 pktFilter=pkt_filter_downstream)
191 UP4.buildUdpPacket(pdn_host,
192 dst_eth=up4.router_mac,
193 src_ip=pdn_interface["ips"][0],
Daniele Moro522023c2021-10-15 17:30:33 +0200194 dst_ip=bess_ue_address,
Daniele Morobf53dec2021-09-13 18:11:56 +0200195 src_udp=PDN_PORT,
196 dst_udp=UE_PORT)
197 pdn_host.sendPacket()
198
199 packets = UP4.checkFilterAndGetPackets(bess_host)
200
201 tot_packets = packets.count('Ether')
202 utilities.assert_equal(expect=True,
203 actual=tot_packets == 1,
204 onpass="BESS correctly received 1 packet",
205 onfail="ERROR: BESS received %d packets" % (
206 tot_packets))
207
208 # ------- BESS -> fabric -> eNB (encapped)
209 main.step("Test downstream BESS -> fabric -> eNB")
210 pkt_filter_downstream = "ip and udp src port %d and udp dst port %d and src host %s and dst host %s" % (
Daniele Moro522023c2021-10-15 17:30:33 +0200211 GPDU_PORT, GPDU_PORT, bess_s1u_address, enodeb_address)
Daniele Morobf53dec2021-09-13 18:11:56 +0200212 main.log.info("Start listening on %s intf %s" % (
Daniele Moro522023c2021-10-15 17:30:33 +0200213 enodeb_host.name, enodeb_interface))
Daniele Morobf53dec2021-09-13 18:11:56 +0200214 main.log.debug(
215 "BPF Filter BESS Downstream: \n %s" % pkt_filter_downstream)
Daniele Moro522023c2021-10-15 17:30:33 +0200216 enodeb_host.startFilter(ifaceName=enodeb_interface,
Daniele Morobf53dec2021-09-13 18:11:56 +0200217 sniffCount=1,
218 pktFilter=pkt_filter_downstream)
219 # Build GTP packet from BESS host
220 UP4.buildGtpPacket(bess_host,
221 src_ip_outer=bess_s1u_address,
Daniele Moro522023c2021-10-15 17:30:33 +0200222 dst_ip_outer=enodeb_address,
Daniele Morobf53dec2021-09-13 18:11:56 +0200223 src_ip_inner=pdn_interface["ips"][0],
Daniele Moro522023c2021-10-15 17:30:33 +0200224 dst_ip_inner=bess_ue_address,
Daniele Morobf53dec2021-09-13 18:11:56 +0200225 src_udp_inner=PDN_PORT,
226 dst_udp_inner=UE_PORT,
227 teid=BESS_TEID)
228 bess_host.sendPacket()
229
230 packets = UP4.checkFilterAndGetPackets(enodeb_host)
231
232 # FIXME: with newer scapy TEID becomes teid (required for Scapy 2.4.5)
233 n_packets = packets.count("TEID=" + hex(BESS_TEID) + "L ")
234 tot_packets = packets.count('Ether')
235 utilities.assert_equal(expect=True,
236 actual=n_packets == 1 and tot_packets == 1,
237 onpass="eNodeB correctly received 1 GTP encapped packet",
238 onfail="ERROR: eNodeb received %d GTP encapped packets and filter captured %d packets" % (
239 n_packets, tot_packets))
240 # ------------------------------------------------
241
Daniele Moro49a843c2022-01-05 14:36:32 +0100242 main.step("Remove and Verify UPF entities for UEs via UP4")
Daniele Morobf53dec2021-09-13 18:11:56 +0200243 up4.detachUes()
Daniele Morobf53dec2021-09-13 18:11:56 +0200244 up4.verifyNoUesFlow(onos_cli)
245
246 main.step("Stop scapy and p4rt client")
247 up4.teardown()
248 bess_host.stopScapy()
Daniele Moroc99bf822021-10-11 23:21:15 +0200249
Daniele Morobf53dec2021-09-13 18:11:56 +0200250 run.cleanup(main)
Daniele Moro954e2282021-09-22 17:32:03 +0200251
252 def CASE3(self, main):
253 main.case("Verify UP4 from different ONOS instances")
254 """
Daniele Moro49a843c2022-01-05 14:36:32 +0100255 Program UPF entitiesvia UP4 on first ONOS instance
Daniele Moro954e2282021-09-22 17:32:03 +0200256 Repeat for all ONOS Instances:
Daniele Moro49a843c2022-01-05 14:36:32 +0100257 Verify UPF entities via P4RT
Daniele Moro954e2282021-09-22 17:32:03 +0200258 Disconnect P4RT client
Daniele Moro49a843c2022-01-05 14:36:32 +0100259 Verify and delete UPF entities via UP4 on the third ONOS instance
Daniele Moro954e2282021-09-22 17:32:03 +0200260 Repeat for all ONOS Instance:
Daniele Moro49a843c2022-01-05 14:36:32 +0100261 Verify removed UPF entities via P4RT
Daniele Moro954e2282021-09-22 17:32:03 +0200262 Disconnect P4RT client
263 """
264 try:
Daniele Moro54581242022-02-25 19:56:02 +0100265 from tests.USECASE.SegmentRouting.dependencies.up4 import UP4
Daniele Moro954e2282021-09-22 17:32:03 +0200266 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import \
267 Testcaselib as run
268 except ImportError as e:
269 main.log.error("Import not found. Exiting the test")
270 main.log.error(e)
271 main.cleanAndExit()
Daniele Moroc6811a82021-10-12 11:29:41 +0200272 n_switches = int(main.params["TOPO"]["switchNum"])
Daniele Moro954e2282021-09-22 17:32:03 +0200273
274 run.initTest(main)
275 main.log.info(main.Cluster.numCtrls)
276 main.Cluster.setRunningNode(3)
277 run.installOnos(main, skipPackage=True, cliSleep=5)
278
279 onos_cli_0 = main.Cluster.active(0).CLI
280 onos_cli_1 = main.Cluster.active(1).CLI
281 onos_cli_2 = main.Cluster.active(2).CLI
282 up4_0 = UP4()
283 up4_1 = UP4()
284 up4_2 = UP4()
285
Daniele Moro49a843c2022-01-05 14:36:32 +0100286 main.step("Program and Verify UPF entities via UP4 on ONOS 0")
Daniele Moro954e2282021-09-22 17:32:03 +0200287 up4_0.setup(main.Cluster.active(0).p4rtUp4, no_host=True)
288 up4_0.attachUes()
289 up4_0.verifyUp4Flow(onos_cli_0)
290 up4_0.teardown()
291
Daniele Moro49a843c2022-01-05 14:36:32 +0100292 main.step("Verify UPF entities number via UP4 P4RT on ONOS 1")
Daniele Moro954e2282021-09-22 17:32:03 +0200293 up4_1.setup(main.Cluster.active(1).p4rtUp4, no_host=True)
294 utilities.assert_equal(
295 expect=True,
296 actual=up4_1.verifyUesFlowNumberP4rt(),
Daniele Moro49a843c2022-01-05 14:36:32 +0100297 onpass="Correct number of UPF entities",
298 onfail="Wrong number of UPF entities"
Daniele Moro954e2282021-09-22 17:32:03 +0200299 )
300 up4_1.teardown()
301
Daniele Moro49a843c2022-01-05 14:36:32 +0100302 main.step("Verify UPF entities number via UP4 P4RT on ONOS 2")
Daniele Moro954e2282021-09-22 17:32:03 +0200303 up4_2.setup(main.Cluster.active(2).p4rtUp4, no_host=True)
304 utilities.assert_equal(
305 expect=True,
306 actual=up4_2.verifyUesFlowNumberP4rt(),
Daniele Moro49a843c2022-01-05 14:36:32 +0100307 onpass="Correct number of UPF entities",
308 onfail="Wrong number of UPF entities"
Daniele Moro954e2282021-09-22 17:32:03 +0200309 )
310
311 main.step("Verify all ONOS instances have the same number of flows")
312 onos_0_flow_count = onos_cli_0.checkFlowCount()
313 onos_1_flow_count = onos_cli_1.checkFlowCount()
314 onos_2_flow_count = onos_cli_2.checkFlowCount()
315 utilities.assert_equal(
316 expect=True,
317 actual=onos_0_flow_count == onos_1_flow_count == onos_2_flow_count,
318 onpass="All ONOS instances have the same number of flows",
319 onfail="ONOS instances have different number of flows: (%d, %d, %d)" % (
320 onos_0_flow_count, onos_1_flow_count, onos_2_flow_count)
321 )
322
Daniele Moro49a843c2022-01-05 14:36:32 +0100323 main.step("Remove and Verify UPF entities via UP4 on ONOS 2")
Daniele Moro954e2282021-09-22 17:32:03 +0200324 up4_2.detachUes()
325 up4_2.verifyNoUesFlow(onos_cli_2)
326
Daniele Moro49a843c2022-01-05 14:36:32 +0100327 main.step("Verify no UPF entities via UP4 P4RT on ONOS 2")
Daniele Moro954e2282021-09-22 17:32:03 +0200328 utilities.assert_equal(
329 expect=True,
330 actual=up4_2.verifyNoUesFlowNumberP4rt(),
Daniele Moro49a843c2022-01-05 14:36:32 +0100331 onpass="No UPF entities",
332 onfail="Stale UPF entities"
Daniele Moro954e2282021-09-22 17:32:03 +0200333 )
334 up4_2.teardown()
335
Daniele Moro49a843c2022-01-05 14:36:32 +0100336 main.step("Verify no UPF entities via UP4 P4RT on ONOS 1")
Daniele Moro954e2282021-09-22 17:32:03 +0200337 up4_1.setup(main.Cluster.active(1).p4rtUp4, no_host=True)
338 utilities.assert_equal(
339 expect=True,
340 actual=up4_1.verifyNoUesFlowNumberP4rt(),
Daniele Moro49a843c2022-01-05 14:36:32 +0100341 onpass="No UPF entities",
342 onfail="Stale UPF entities"
Daniele Moro954e2282021-09-22 17:32:03 +0200343 )
344 up4_1.teardown()
345
Daniele Moro49a843c2022-01-05 14:36:32 +0100346 main.step("Verify no UPF entities via UP4 P4RT on ONOS 0")
Daniele Moro954e2282021-09-22 17:32:03 +0200347 up4_0.setup(main.Cluster.active(0).p4rtUp4, no_host=True)
348 utilities.assert_equal(
349 expect=True,
350 actual=up4_0.verifyNoUesFlowNumberP4rt(),
Daniele Moro49a843c2022-01-05 14:36:32 +0100351 onpass="No UPF entities",
352 onfail="Stale UPF entities"
Daniele Moro954e2282021-09-22 17:32:03 +0200353 )
354 up4_0.teardown()
355
356 main.step("Verify all ONOS instances have the same number of flows")
357 onos_0_flow_count = onos_cli_0.checkFlowCount()
358 onos_1_flow_count = onos_cli_1.checkFlowCount()
359 onos_2_flow_count = onos_cli_2.checkFlowCount()
360 utilities.assert_equal(
361 expect=True,
362 actual=onos_0_flow_count == onos_1_flow_count == onos_2_flow_count,
363 onpass="All ONOS instances have the same number of flows",
364 onfail="ONOS instances have different number of flows: (%d, %d, %d)" % (
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200365 onos_0_flow_count, onos_1_flow_count, onos_2_flow_count)
Daniele Moro954e2282021-09-22 17:32:03 +0200366 )
Daniele Moroc99bf822021-10-11 23:21:15 +0200367
Daniele Moro954e2282021-09-22 17:32:03 +0200368 run.cleanup(main)
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200369
370 def CASE4(self, main):
371 main.case("Verify UP4 wipe-out after ONOS reboot")
372 """
Daniele Moro49a843c2022-01-05 14:36:32 +0100373 Program UPF entities
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200374 Kill ONOS POD
Daniele Moro49a843c2022-01-05 14:36:32 +0100375 Verify UPF entities from other ONOS instances
376 Remove UPF entities
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200377 Wait/Verify ONOS is back
Daniele Moro49a843c2022-01-05 14:36:32 +0100378 Verify no UPF entities from rebooted instance
379 Re-program UPF entities from rebooted instance
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200380 Verify all instances have same number of flows
Daniele Moro49a843c2022-01-05 14:36:32 +0100381 Remove UPF entities (cleanup)
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200382 """
383 try:
Daniele Moro54581242022-02-25 19:56:02 +0100384 from tests.USECASE.SegmentRouting.dependencies.up4 import UP4
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200385 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import \
386 Testcaselib as run
Daniele Moro5d88e2a2021-11-12 17:47:55 +0100387 from tests.USECASE.SegmentRouting.SRStaging.dependencies.SRStagingTest import \
388 SRStagingTest
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200389 except ImportError as e:
390 main.log.error("Import not found. Exiting the test")
391 main.log.error(e)
392 main.cleanAndExit()
Daniele Moroc6811a82021-10-12 11:29:41 +0200393 n_switches = int(main.params["TOPO"]["switchNum"])
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200394
395 run.initTest(main)
396 main.log.info(main.Cluster.numCtrls)
397 main.Cluster.setRunningNode(3)
398 run.installOnos(main, skipPackage=True, cliSleep=5)
399
400 onos_cli_0 = main.Cluster.active(0).CLI
401 onos_cli_1 = main.Cluster.active(1).CLI
402 onos_cli_2 = main.Cluster.active(2).CLI
Daniele Moro5d88e2a2021-11-12 17:47:55 +0100403 ctrl_0 = main.Cluster.active(0)
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200404
405 up4_0 = UP4()
406 up4_1 = UP4()
407 up4_2 = UP4()
408
Daniele Moro49a843c2022-01-05 14:36:32 +0100409 main.step("Program and Verify UPF entities via UP4 on ONOS 0")
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200410 up4_0.setup(main.Cluster.active(0).p4rtUp4, no_host=True)
411 up4_0.attachUes()
412 up4_0.verifyUp4Flow(onos_cli_0)
413 up4_0.teardown()
414
415 onosPod = main.params["UP4_delete_pod"]
Daniele Moroc99bf822021-10-11 23:21:15 +0200416
417 # Save ONOS diags of the POD we are killing otherwise we lose ONOS logs
418 main.ONOSbench.onosDiagnosticsK8s(
419 [onosPod],
420 main.logdir,
421 "-CASE%d-%s_BeforeKill" % (main.CurrentTestCaseNumber, onosPod)
422 )
423
Daniele Moro5d88e2a2021-11-12 17:47:55 +0100424 onosK8sNode = SRStagingTest.onosDown(main, ctrl_0, preventRestart=True)
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200425
Daniele Moro49a843c2022-01-05 14:36:32 +0100426 main.step("Verify UPF entities number via UP4 P4RT on ONOS 2")
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200427 up4_2.setup(main.Cluster.active(2).p4rtUp4, no_host=True)
428 utilities.assert_equal(
429 expect=True,
430 actual=up4_2.verifyUesFlowNumberP4rt(),
Daniele Moro49a843c2022-01-05 14:36:32 +0100431 onpass="Correct number of UPF entities",
432 onfail="Wrong number of UPF entities"
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200433 )
434
Daniele Moro49a843c2022-01-05 14:36:32 +0100435 main.step("Remove and Verify UPF entities via UP4 on ONOS 2")
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200436 up4_2.detachUes()
437 up4_2.verifyNoUesFlow(onos_cli_2)
438
Daniele Moro49a843c2022-01-05 14:36:32 +0100439 main.step("Verify no UPF entities via UP4 P4RT on ONOS 2")
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200440 utilities.assert_equal(
441 expect=True,
442 actual=up4_2.verifyNoUesFlowNumberP4rt(),
Daniele Moro49a843c2022-01-05 14:36:32 +0100443 onpass="No UPF entities",
444 onfail="Stale UPF entities"
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200445 )
446 up4_2.teardown()
447
Daniele Moroc6811a82021-10-12 11:29:41 +0200448 main.step(
449 "Verify all active ONOS instances have the same number of flows")
Daniele Moro9ba5cf02021-10-08 18:00:56 +0200450 onos_1_flow_count = onos_cli_1.checkFlowCount()
451 onos_2_flow_count = onos_cli_2.checkFlowCount()
452 utilities.assert_equal(
453 expect=True,
454 actual=onos_1_flow_count == onos_2_flow_count,
455 onpass="All ONOS instances have the same number of flows",
456 onfail="ONOS instances have different number of flows: (%d, %d)" % (
457 onos_1_flow_count, onos_2_flow_count)
458 )
459
Daniele Moro5d88e2a2021-11-12 17:47:55 +0100460 SRStagingTest.onosUp(main, onosK8sNode, ctrl_0)
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200461
462 main.step("Verify ONOS cluster is in good shape")
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200463 onosNodesStatus = utilities.retry(
464 f=main.Cluster.nodesCheck,
465 retValue=False,
466 sleep=5,
467 attempts=10
468 )
469 utilities.assert_equal(
470 expect=True,
471 actual=onosNodesStatus,
472 onpass="ONOS nodes status correct",
473 onfail="Wrong ONOS nodes status"
474 )
475
Daniele Moro49a843c2022-01-05 14:36:32 +0100476 main.step("Verify no UPF entities via UP4 P4RT on ONOS 0")
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200477 up4_0.setup(main.Cluster.active(0).p4rtUp4, no_host=True)
478 utilities.assert_equal(
479 expect=True,
480 actual=up4_0.verifyNoUesFlowNumberP4rt(),
Daniele Moro49a843c2022-01-05 14:36:32 +0100481 onpass="No UPF entities",
482 onfail="Stale UPF entities"
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200483 )
484
Daniele Moro49a843c2022-01-05 14:36:32 +0100485 main.step("Re-program UPF entities via UP4 on ONOS 0 after restart")
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200486 up4_0.attachUes()
487 up4_0.verifyUp4Flow(onos_cli_0)
488 up4_0.teardown()
489
Daniele Moro49a843c2022-01-05 14:36:32 +0100490 main.step("Verify UPF entities via UP4 on ONOS 1")
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200491 up4_1.setup(main.Cluster.active(1).p4rtUp4, no_host=True)
492 up4_1.verifyUp4Flow(onos_cli_1)
493
494 main.step("Verify all ONOS instances have the same number of flows")
495 onos_0_flow_count = onos_cli_0.checkFlowCount()
496 onos_1_flow_count = onos_cli_1.checkFlowCount()
497 onos_2_flow_count = onos_cli_2.checkFlowCount()
498 utilities.assert_equal(
499 expect=True,
500 actual=onos_0_flow_count == onos_1_flow_count == onos_2_flow_count,
501 onpass="All ONOS instances have the same number of flows",
502 onfail="ONOS instances have different number of flows: (%d, %d, %d)" % (
503 onos_0_flow_count, onos_1_flow_count, onos_2_flow_count)
504 )
505
Daniele Moro49a843c2022-01-05 14:36:32 +0100506 main.step("Cleanup UPF entities via UP4 on ONOS 1")
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200507 up4_1.detachUes()
Daniele Moro6dfbfef2021-09-28 22:44:19 +0200508 up4_1.verifyNoUesFlow(onos_cli_1)
Daniele Moroe1d05eb2021-09-23 19:52:30 +0200509 up4_1.teardown()
510
511 run.cleanup(main)
Daniele Moro522023c2021-10-15 17:30:33 +0200512
513 def CASE5(self, main):
514 main.case("UP4 Data Plane Failure Test")
515 """
Daniele Moro49a843c2022-01-05 14:36:32 +0100516 Program UPF entities
Daniele Moro522023c2021-10-15 17:30:33 +0200517 Kill one switch
Daniele Moro80271cb2021-11-11 20:08:51 +0100518 Set label on switch K8S node to prevent K8S to redeploy stratum
Daniele Moro522023c2021-10-15 17:30:33 +0200519 Verify that traffic from eNodebs that are connected to that switch fails
520 Verify that traffic from other eNodeBs is being forwarded
521 Wait for the switch to be up again
522 Check flows
Daniele Moro49a843c2022-01-05 14:36:32 +0100523 Remove UPF entities (cleanup)
Daniele Moro522023c2021-10-15 17:30:33 +0200524 """
525 try:
Daniele Moro54581242022-02-25 19:56:02 +0100526 from tests.USECASE.SegmentRouting.dependencies.up4 import UP4
Daniele Moro522023c2021-10-15 17:30:33 +0200527 from tests.USECASE.SegmentRouting.dependencies.Testcaselib import \
528 Testcaselib as run
529 from tests.USECASE.SegmentRouting.SRStaging.dependencies.SRStagingTest import \
530 SRStagingTest
531 import time
532 import itertools
533 except ImportError as e:
534 main.log.error("Import not found. Exiting the test")
535 main.log.error(e)
536 main.cleanAndExit()
537 n_switches = int(main.params["TOPO"]["switchNum"])
Daniele Moro80271cb2021-11-11 20:08:51 +0100538 switch_to_kill = main.params["UP4"]["UP4_dataplane_fail"]["switch_to_kill"]
539 k8s_switch_node = main.params["UP4"]["UP4_dataplane_fail"]["k8s_switch_node"]
540 k8s_label = main.params["UP4"]["UP4_dataplane_fail"]["k8s_label"]
541 k8s_label_value_test = main.params["UP4"]["UP4_dataplane_fail"]["k8s_label_value_test"]
542 k8s_label_value_normal = main.params["UP4"]["UP4_dataplane_fail"]["k8s_label_value_normal"]
Daniele Moro522023c2021-10-15 17:30:33 +0200543
544 run.initTest(main)
545 main.log.info(main.Cluster.numCtrls)
546 main.Cluster.setRunningNode(3)
547 run.installOnos(main, skipPackage=True, cliSleep=5)
548
549 onos_cli = main.Cluster.active(0).CLI
Daniele Moro80271cb2021-11-11 20:08:51 +0100550 kubectl = main.Cluster.active(0).Bench
551 kubeconfig = main.Cluster.active(0).k8s.kubeConfig
552 namespace = main.params['kubernetes']['namespace']
Daniele Moro522023c2021-10-15 17:30:33 +0200553
554 up4 = UP4()
555
Daniele Moro49a843c2022-01-05 14:36:32 +0100556 main.step("Program and Verify UPF entities via UP4")
Daniele Moro522023c2021-10-15 17:30:33 +0200557 up4.setup(main.Cluster.active(0).p4rtUp4)
558 up4.attachUes()
559 up4.verifyUp4Flow(onos_cli)
560
Daniele Moro80271cb2021-11-11 20:08:51 +0100561 main.step("Set label to switch k8s node and kill switch")
562 # K8s node name correspond to the switch name in lowercase
Daniele Moro522023c2021-10-15 17:30:33 +0200563 utilities.assert_equal(
Daniele Moro80271cb2021-11-11 20:08:51 +0100564 expect=main.TRUE,
565 actual=kubectl.kubectlSetLabel(
566 nodeName=k8s_switch_node,
567 label=k8s_label,
568 value=k8s_label_value_test,
569 kubeconfig=kubeconfig,
570 namespace=namespace,
571 ),
572 onpass="Label has been set correctly on node %s" % k8s_switch_node,
573 onfail="Label has not been set on node %s" % k8s_switch_node
Daniele Moro522023c2021-10-15 17:30:33 +0200574 )
Daniele Moro80271cb2021-11-11 20:08:51 +0100575 try:
576 def checkNumberStratumPods(n_value):
577 pods = kubectl.kubectlGetPodNames(
578 kubeconfig=kubeconfig,
579 namespace=namespace,
580 name="stratum"
581 )
582 main.log.info("PODS: " + str(pods))
583 return n_value == len(pods) if pods is not main.FALSE else False
584 # Execute the following in try/except/finally to be sure to restore the
585 # k8s label even in case of unhandled exception.
Daniele Moro522023c2021-10-15 17:30:33 +0200586
Daniele Moro80271cb2021-11-11 20:08:51 +0100587 # Wait for stratum pod to be removed from the switch
588 removed = utilities.retry(checkNumberStratumPods,
589 False,
590 args=[n_switches-1],
591 attempts=50
592 )
593 main.log.info("Stratum has been removed from the switch? %s" % removed)
Daniele Moro522023c2021-10-15 17:30:33 +0200594
Daniele Moro80271cb2021-11-11 20:08:51 +0100595 switch_component = getattr(main, switch_to_kill)
596 switch_component.handle.sendline("sudo reboot")
Daniele Moro522023c2021-10-15 17:30:33 +0200597
Daniele Moro80271cb2021-11-11 20:08:51 +0100598 sleepTime = 20
599 main.log.info("Sleeping %s seconds for Fabric to react" % sleepTime)
600 time.sleep(sleepTime)
Daniele Moro522023c2021-10-15 17:30:33 +0200601
Daniele Moro80271cb2021-11-11 20:08:51 +0100602 available = utilities.retry(SRStagingTest.switchIsConnected,
603 True,
604 args=[switch_component],
605 attempts=300,
606 getRetryingTime=True)
607 main.log.info("Switch %s is available in ONOS? %s" % (
608 switch_to_kill, available))
609 utilities.assert_equal(
610 expect=True,
611 actual=not available and removed,
612 onpass="Switch was rebooted (ONL reboot) successfully and stratum" +
613 " removed from switch k8s node",
614 onfail="Switch was not rebooted (ONL reboot) successfully or stratum " +
615 "not removed from switch k8s node"
616 )
617
618 enodebs_fail = main.params["UP4"]["UP4_dataplane_fail"]["enodebs_fail"].split(",")
619 enodebs_no_fail = list(set(up4.enodebs.keys()) - set(enodebs_fail))
620
Daniele Moro80271cb2021-11-11 20:08:51 +0100621
Daniele Morobef0c7e2022-02-16 17:47:13 -0800622 for app_filter_name in up4.app_filters:
623 # Failure only when we forward traffic, when dropping we should
624 # still see traffic being dropped.
625 if up4.app_filters["action"] == "allow":
626 main.step("Test upstream traffic FAIL %s" % app_filter_name)
627 up4.testUpstreamTraffic(enb_names=enodebs_fail, app_filter_name=app_filter_name, shouldFail=True)
628 main.step("Test downstream traffic FAIL %s" % app_filter_name)
629 up4.testDownstreamTraffic(enb_names=enodebs_fail, app_filter_name=app_filter_name, shouldFail=True)
630 else:
631 main.step("Test upstream traffic FAIL %s" % app_filter_name)
632 up4.testUpstreamTraffic(enb_names=enodebs_fail, app_filter_name=app_filter_name)
633 main.step("Test downstream traffic FAIL %s" % app_filter_name)
634 up4.testDownstreamTraffic(enb_names=enodebs_fail, app_filter_name=app_filter_name)
635
636 main.step("Test upstream traffic NO FAIL %s" % app_filter_name)
637 up4.testUpstreamTraffic(enb_names=enodebs_no_fail, app_filter_name=app_filter_name)
638 main.step("Test downstream traffic NO FAIL %s" % app_filter_name)
639 up4.testDownstreamTraffic(enb_names=enodebs_no_fail, app_filter_name=app_filter_name)
640
Daniele Moro80271cb2021-11-11 20:08:51 +0100641 except Exception as e:
642 main.log.error("Unhandled exception!")
643 main.log.error(e)
644 finally:
645 utilities.assert_equal(
646 expect=main.TRUE,
647 actual=kubectl.kubectlSetLabel(
648 nodeName=k8s_switch_node,
649 label=k8s_label,
650 value=k8s_label_value_normal,
651 kubeconfig=kubeconfig,
652 namespace=namespace,
653 ),
654 onpass="Label has been set correctly on node %s" % k8s_switch_node,
655 onfail="Label has not been set on node %s" % k8s_switch_node
656 )
657 # Reconnect to the switch
658 connect = utilities.retry(switch_component.connect,
659 main.FALSE,
660 attempts=30,
661 getRetryingTime=True)
662 main.log.info("Connected to the switch %s? %s" % (
663 switch_to_kill, connect))
664
665 # Wait for stratum pod to be re-deployed on the switch
666 deployed = utilities.retry(checkNumberStratumPods,
667 False,
668 args=[n_switches],
669 attempts=50
670 )
671 main.log.info("Stratum has been redeployed on the switch? %s" % deployed)
672
673 # Wait switch to be back in ONOS
674 available = utilities.retry(SRStagingTest.switchIsConnected,
675 False,
676 args=[switch_component],
677 attempts=300,
678 getRetryingTime=True)
679 main.log.info("Switch %s is available in ONOS? %s" % (
680 switch_to_kill, available))
681 utilities.assert_equal(
682 expect=True,
683 actual=available and connect == main.TRUE and deployed,
684 onpass="Switch is back available in ONOS and stratum has been redeployed",
685 onfail="Switch is not available in ONOS, may influence subsequent tests!"
686 )
Daniele Moro522023c2021-10-15 17:30:33 +0200687
Daniele Morobef0c7e2022-02-16 17:47:13 -0800688 for app_filter_name in up4.app_filters:
689 main.step("Test upstream traffic AFTER switch reboot %s" % app_filter_name)
690 up4.testUpstreamTraffic(app_filter_name=app_filter_name)
Daniele Moro522023c2021-10-15 17:30:33 +0200691
Daniele Moro49a843c2022-01-05 14:36:32 +0100692 main.step("Cleanup UPF entities via UP4")
Daniele Moro522023c2021-10-15 17:30:33 +0200693 up4.detachUes()
694 up4.verifyNoUesFlow(onos_cli)
695 up4.teardown()
696
Daniele Moro522023c2021-10-15 17:30:33 +0200697 # Teardown
698 run.cleanup(main)
Daniele Moro80271cb2021-11-11 20:08:51 +0100699