blob: d1eba2131111a0c565a55f9ffd0d37a1b88cc6e6 [file] [log] [blame]
Andrea Campanella01e886e2017-12-15 15:27:31 +01001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.t3.impl;
17
18import com.google.common.collect.ImmutableList;
19import com.google.common.collect.ImmutableSet;
20import org.junit.Before;
21import org.junit.Test;
Andrea Campanella37d10622018-01-18 17:11:42 +010022import org.onlab.packet.ChassisId;
Andrea Campanella01e886e2017-12-15 15:27:31 +010023import org.onlab.packet.EthType;
24import org.onlab.packet.IpAddress;
25import org.onlab.packet.MacAddress;
26import org.onlab.packet.VlanId;
Andrea Campanella7c8e7912018-01-23 12:46:04 +010027import org.onosproject.cluster.NodeId;
Andrea Campanella01e886e2017-12-15 15:27:31 +010028import org.onosproject.net.ConnectPoint;
Andrea Campanella37d10622018-01-18 17:11:42 +010029import org.onosproject.net.DefaultAnnotations;
30import org.onosproject.net.DefaultDevice;
Andrea Campanella01e886e2017-12-15 15:27:31 +010031import org.onosproject.net.DefaultLink;
Andrea Campanella04924b92018-01-17 16:34:51 +010032import org.onosproject.net.DefaultPort;
Andrea Campanella37d10622018-01-18 17:11:42 +010033import org.onosproject.net.Device;
Andrea Campanella01e886e2017-12-15 15:27:31 +010034import org.onosproject.net.DeviceId;
35import org.onosproject.net.Host;
36import org.onosproject.net.Link;
Andrea Campanella04924b92018-01-17 16:34:51 +010037import org.onosproject.net.Port;
Andrea Campanella7cb4fd82018-02-27 12:36:00 +010038import org.onosproject.net.PortNumber;
Andrea Campanella01e886e2017-12-15 15:27:31 +010039import org.onosproject.net.flow.FlowEntry;
Andrea Campanella01e886e2017-12-15 15:27:31 +010040import org.onosproject.net.flow.TrafficSelector;
41import org.onosproject.net.flow.criteria.Criterion;
42import org.onosproject.net.flow.criteria.EthTypeCriterion;
Seyeon Jeong351ed582020-04-07 12:06:18 -070043import org.onosproject.net.flow.criteria.MplsCriterion;
Andrea Campanella01e886e2017-12-15 15:27:31 +010044import org.onosproject.net.flow.criteria.VlanIdCriterion;
45import org.onosproject.net.group.Group;
Andrea Campanella01e886e2017-12-15 15:27:31 +010046import org.onosproject.net.provider.ProviderId;
Andrea Campanellacc2424a2018-03-07 14:27:54 -080047import org.onosproject.routeservice.ResolvedRoute;
Seyeon Jeong357bcec2020-02-28 01:17:34 -080048import org.onosproject.t3.api.DeviceNib;
49import org.onosproject.t3.api.DriverNib;
50import org.onosproject.t3.api.EdgePortNib;
51import org.onosproject.t3.api.FlowNib;
52import org.onosproject.t3.api.GroupNib;
53import org.onosproject.t3.api.HostNib;
54import org.onosproject.t3.api.LinkNib;
55import org.onosproject.t3.api.MastershipNib;
56import org.onosproject.t3.api.RouteNib;
Andrea Campanella01e886e2017-12-15 15:27:31 +010057import org.onosproject.t3.api.StaticPacketTrace;
58import org.slf4j.Logger;
59
Andrea Campanellacc2424a2018-03-07 14:27:54 -080060import java.util.Optional;
Andrea Campanella01e886e2017-12-15 15:27:31 +010061import java.util.Set;
62
63import static org.junit.Assert.assertEquals;
64import static org.junit.Assert.assertNotNull;
65import static org.junit.Assert.assertNull;
66import static org.junit.Assert.assertTrue;
Andrea Campanella37d10622018-01-18 17:11:42 +010067import static org.onosproject.net.Device.Type.SWITCH;
Andrea Campanella01e886e2017-12-15 15:27:31 +010068import static org.onosproject.t3.impl.T3TestObjects.*;
Andrea Campanella6f2d6742018-02-07 12:00:12 +010069import static org.onosproject.t3.impl.TroubleshootManager.PACKET_TO_CONTROLLER;
Andrea Campanella01e886e2017-12-15 15:27:31 +010070import static org.slf4j.LoggerFactory.getLogger;
71
72/**
73 * Test Class for Troubleshoot Manager.
74 */
75public class TroubleshootManagerTest {
76
77 private static final Logger log = getLogger(TroubleshootManager.class);
78
79 private TroubleshootManager mngr;
80
81 @Before
82 public void setUp() throws Exception {
83 mngr = new TroubleshootManager();
Seyeon Jeong357bcec2020-02-28 01:17:34 -080084
85 mngr.flowNib = new TestFlowRuleService();
86 mngr.groupNib = new TestGroupService();
87 mngr.hostNib = new TestHostService();
88 mngr.linkNib = new TestLinkService();
89 mngr.deviceNib = new TestDeviceService();
90 mngr.driverNib = new TestDriverService();
91 mngr.mastershipNib = new TestMastershipService();
92 mngr.edgePortNib = new TestEdgePortService();
93 mngr.routeNib = new TestRouteService();
Andrea Campanella01e886e2017-12-15 15:27:31 +010094
95 assertNotNull("Manager should not be null", mngr);
96
Seyeon Jeong357bcec2020-02-28 01:17:34 -080097 assertNotNull("Flow rule Service should not be null", mngr.flowNib);
98 assertNotNull("Group Service should not be null", mngr.groupNib);
99 assertNotNull("Host Service should not be null", mngr.hostNib);
100 assertNotNull("Link Service should not be null", mngr.linkNib);
101 assertNotNull("Device Service should not be null", mngr.deviceNib);
102 assertNotNull("Driver Service should not be null", mngr.driverNib);
103 assertNotNull("Mastership Service should not be null", mngr.driverNib);
104 assertNotNull("EdgePort Service should not be null", mngr.driverNib);
105 assertNotNull("Route Service should not be null", mngr.routeNib);
Andrea Campanella37d10622018-01-18 17:11:42 +0100106 }
107
108 /**
109 * Tests failure on non existent device.
110 */
111 @Test(expected = NullPointerException.class)
112 public void nonExistentDevice() {
113 StaticPacketTrace traceFail = mngr.trace(PACKET_OK, ConnectPoint.deviceConnectPoint("nonexistent" + "/1"));
114 }
115
116 /**
117 * Tests failure on offline device.
118 */
119 @Test
120 public void offlineDevice() {
121 StaticPacketTrace traceFail = mngr.trace(PACKET_OK, ConnectPoint.deviceConnectPoint(OFFLINE_DEVICE + "/1"));
122 assertNotNull("Trace should not be null", traceFail);
123 assertNull("Trace should have 0 output", traceFail.getGroupOuputs(SINGLE_FLOW_DEVICE));
Andrea Campanellabb9d3fb2018-01-22 15:10:30 +0100124 }
125
126 /**
127 * Tests failure on same output.
128 */
129 @Test
130 public void sameOutput() {
131 StaticPacketTrace traceFail = mngr.trace(PACKET_OK, SAME_OUTPUT_FLOW_CP);
132 assertNotNull("Trace should not be null", traceFail);
133 assertTrue("Trace should be unsuccessful",
134 traceFail.resultMessage().contains("is same as initial input"));
Andrea Campanella37d10622018-01-18 17:11:42 +0100135 log.info("trace {}", traceFail.resultMessage());
Andrea Campanella01e886e2017-12-15 15:27:31 +0100136 }
137
Andrea Campanella7c8e7912018-01-23 12:46:04 +0100138 /**
139 * Tests ARP to controller.
140 */
141 @Test
142 public void arpToController() {
143 StaticPacketTrace traceSuccess = mngr.trace(PACKET_ARP, ARP_FLOW_CP);
144 assertNotNull("Trace should not be null", traceSuccess);
145 assertTrue("Trace should be successful",
Andrea Campanella6f2d6742018-02-07 12:00:12 +0100146 traceSuccess.resultMessage().contains(PACKET_TO_CONTROLLER));
Andrea Campanella7c8e7912018-01-23 12:46:04 +0100147 assertTrue("Master should be Master1",
148 traceSuccess.resultMessage().contains(MASTER_1));
149 ConnectPoint connectPoint = traceSuccess.getGroupOuputs(ARP_FLOW_DEVICE).get(0).getOutput();
150 assertEquals("Packet Should go to CONTROLLER", PortNumber.CONTROLLER, connectPoint.port());
Andrea Campanella58b3b522018-02-06 15:46:52 +0100151 assertNull("VlanId should be null", traceSuccess.getGroupOuputs(ARP_FLOW_DEVICE).get(0)
152 .getFinalPacket().getCriterion(Criterion.Type.VLAN_VID));
Andrea Campanella7c8e7912018-01-23 12:46:04 +0100153 log.info("trace {}", traceSuccess.resultMessage());
154 }
155
Andrea Campanellabb9d3fb2018-01-22 15:10:30 +0100156
Andrea Campanella01e886e2017-12-15 15:27:31 +0100157 /**
Andrea Campanella2bc55dd2018-01-18 16:54:34 +0100158 * Tests failure on device with no flows.
Andrea Campanella01e886e2017-12-15 15:27:31 +0100159 */
160 @Test
161 public void noFlows() {
162 StaticPacketTrace traceFail = mngr.trace(PACKET_OK, ConnectPoint.deviceConnectPoint("test/1"));
163 assertNotNull("Trace should not be null", traceFail);
164 assertNull("Trace should have 0 output", traceFail.getGroupOuputs(SINGLE_FLOW_DEVICE));
165 log.info("trace {}", traceFail.resultMessage());
166 }
167
168 /**
Andrea Campanella7cb4fd82018-02-27 12:36:00 +0100169 * Test group with no buckets.
170 */
171 @Test
172 public void noBucketsTest() throws Exception {
173
174 StaticPacketTrace traceFail = mngr.trace(PACKET_OK, NO_BUCKET_CP);
175 assertNotNull("Trace should not be null", traceFail);
176 assertTrue("Trace should be unsuccessful",
177 traceFail.resultMessage().contains("no buckets"));
178 log.info("trace {}", traceFail.resultMessage());
179
180 }
181
182 /**
Andrea Campanella01e886e2017-12-15 15:27:31 +0100183 * Test a single flow rule that has output port in it.
184 */
185 @Test
186 public void testSingleFlowRule() {
187
Andrea Campanellae04aac92018-01-31 14:59:03 +0100188 testSuccess(PACKET_OK, SINGLE_FLOW_IN_CP, SINGLE_FLOW_DEVICE, SINGLE_FLOW_OUT_CP, 1, 1);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100189
Andrea Campanellae04aac92018-01-31 14:59:03 +0100190 testFailure(PACKET_FAIL, SINGLE_FLOW_IN_CP, SINGLE_FLOW_DEVICE);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100191 }
192
193 /**
194 * Tests two flow rule the last one of which has output port in it.
195 */
196 @Test
197 public void testDualFlowRule() {
198
199 //Test Success
200
Andrea Campanella2bc55dd2018-01-18 16:54:34 +0100201 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, DUAL_FLOW_IN_CP, DUAL_FLOW_DEVICE,
Andrea Campanellae04aac92018-01-31 14:59:03 +0100202 DUAL_FLOW_OUT_CP, 1, 1);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100203
204 //Testing Vlan
205 Criterion criterion = traceSuccess.getGroupOuputs(DUAL_FLOW_DEVICE).get(0).
206 getFinalPacket().getCriterion(Criterion.Type.VLAN_VID);
207 assertNotNull("Packet Should have Vlan", criterion);
208
209 VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) criterion;
210
211 assertEquals("Vlan should be 100", VlanId.vlanId((short) 100), vlanIdCriterion.vlanId());
212
213 //Test Faliure
Andrea Campanellae04aac92018-01-31 14:59:03 +0100214 testFailure(PACKET_FAIL, DUAL_FLOW_IN_CP, DUAL_FLOW_DEVICE);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100215
216 }
217
218 /**
219 * Test a single flow rule that points to a group with output port in it.
220 */
221 @Test
222 public void flowAndGroup() throws Exception {
223
Andrea Campanella2bc55dd2018-01-18 16:54:34 +0100224 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, GROUP_FLOW_IN_CP, GROUP_FLOW_DEVICE,
Andrea Campanellae04aac92018-01-31 14:59:03 +0100225 GROUP_FLOW_OUT_CP, 1, 1);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100226
227 assertTrue("Wrong Output Group", traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
228 .get(0).getGroups().contains(GROUP));
Andrea Campanella09ca07a2018-01-25 16:44:04 +0100229 assertEquals("Packet should not have MPLS Label", EthType.EtherType.IPV4.ethType(),
230 ((EthTypeCriterion) traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
231 .get(0).getFinalPacket().getCriterion(Criterion.Type.ETH_TYPE)).ethType());
232 assertNull("Packet should not have MPLS Label", traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
233 .get(0).getFinalPacket().getCriterion(Criterion.Type.MPLS_LABEL));
234 assertNull("Packet should not have MPLS Label", traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
235 .get(0).getFinalPacket().getCriterion(Criterion.Type.MPLS_BOS));
Andrea Campanella01e886e2017-12-15 15:27:31 +0100236
237 }
238
239 /**
Seyeon Jeong351ed582020-04-07 12:06:18 -0700240 * Test a single flow rule that points to a group with multiple actions
241 * that need to be executed in the order specified in the OpenFlow spec.
242 */
243 @Test
244 public void testGroupMultipleActionsOrdered() {
245
246 StaticPacketTrace traceSuccess = testSuccess(
247 PACKET_OK, ACTION_ORDER_IN_CP, ACTION_ORDER_DEVICE, ACTION_ORDER_OUT_CP, 1, 1);
248
249 assertEquals("Packet should not have VLAN ID",
250 VlanId.NONE,
251 ((VlanIdCriterion) traceSuccess.getGroupOuputs(ACTION_ORDER_DEVICE)
252 .get(0).getFinalPacket().getCriterion(Criterion.Type.VLAN_VID)).vlanId());
253 assertEquals("Packet should have MPLS label",
254 ACTION_ORDER_MPLS_LABEL,
255 ((MplsCriterion) traceSuccess.getGroupOuputs(ACTION_ORDER_DEVICE)
256 .get(0).getFinalPacket().getCriterion(Criterion.Type.MPLS_LABEL)).label());
257
258 }
259
260 /**
Andrea Campanella01e886e2017-12-15 15:27:31 +0100261 * Test path through a 3 device topology.
262 */
263 @Test
264 public void singlePathTopology() throws Exception {
265
266 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK_TOPO, TOPO_FLOW_1_IN_CP,
Andrea Campanellae04aac92018-01-31 14:59:03 +0100267 TOPO_FLOW_3_DEVICE, TOPO_FLOW_3_OUT_CP, 1, 1);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100268
269 assertTrue("Incorrect path",
270 traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_2_IN_CP));
271 assertTrue("Incorrect path",
272 traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_2_OUT_CP));
273 assertTrue("Incorrect path",
274 traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_3_IN_CP));
275
276 }
277
278 /**
279 * Test path through a 4 device topology with first device that has groups with multiple output buckets.
280 */
281 @Test
282 public void testGroupTopo() throws Exception {
283
284 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK_TOPO, TOPO_FLOW_IN_CP,
Andrea Campanellae04aac92018-01-31 14:59:03 +0100285 TOPO_FLOW_3_DEVICE, TOPO_FLOW_3_OUT_CP, 2, 1);
286
287 log.info("{}", traceSuccess);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100288
289 assertTrue("Incorrect groups",
290 traceSuccess.getGroupOuputs(TOPO_GROUP_FLOW_DEVICE).get(0).getGroups().contains(TOPO_GROUP));
291 assertTrue("Incorrect bucket",
292 traceSuccess.getGroupOuputs(TOPO_GROUP_FLOW_DEVICE).get(1).getGroups().contains(TOPO_GROUP));
293 }
294
295 /**
296 * Test HW support in a single device with 2 flow rules to check hit of static HW rules.
297 */
298 @Test
299 public void hardwareTest() throws Exception {
300
301 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, HARDWARE_DEVICE_IN_CP,
Andrea Campanellae04aac92018-01-31 14:59:03 +0100302 HARDWARE_DEVICE, HARDWARE_DEVICE_OUT_CP, 1, 1);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100303
304 assertEquals("wrong ETH type", EthType.EtherType.IPV4.ethType(),
305 ((EthTypeCriterion) traceSuccess.getGroupOuputs(HARDWARE_DEVICE).get(0).getFinalPacket()
306 .getCriterion(Criterion.Type.ETH_TYPE)).ethType());
307
308 }
309
Andrea Campanellae04aac92018-01-31 14:59:03 +0100310 /**
Andrea Campanella97f9d4c2018-02-06 18:58:40 +0100311 * Test that HW has two rules on table 10 for untagged packets.
312 */
313 @Test
314 public void hardwareTable10Test() throws Exception {
315
316 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, HARDWARE_DEVICE_10_IN_CP,
317 HARDWARE_DEVICE_10, HARDWARE_DEVICE_10_OUT_CP, 1, 1);
318
319 assertTrue("Second flow rule is absent", traceSuccess.getFlowsForDevice(HARDWARE_DEVICE_10)
320 .contains(HARDWARE_10_SECOND_FLOW_ENTRY));
321
322 }
323
324 /**
Andrea Campanellae04aac92018-01-31 14:59:03 +0100325 * Test dual links between 3 topology elements.
326 */
327 @Test
328 public void dualLinks() throws Exception {
329
330 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, DUAL_LINK_1_CP_1_IN,
331 DUAL_LINK_3, DUAL_LINK_3_CP_3_OUT, 4, 1);
332
333 //TODO tests
334
335 }
336
Andrea Campanellad5bb2ef2018-01-31 16:43:23 +0100337 /**
338 * Test proper clear deferred behaviour.
339 */
340 @Test
341 public void clearDeferred() throws Exception {
342
343 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, DEFERRED_CP_1_IN,
344 DEFERRED_1, DEFERRED_CP_2_OUT, 1, 1);
345
346 assertNull("MPLS should have been not applied due to clear deferred", traceSuccess
347 .getGroupOuputs(DEFERRED_1).get(0).getFinalPacket().getCriterion(Criterion.Type.MPLS_LABEL));
348
349 }
350
351
Andrea Campanella6f2d6742018-02-07 12:00:12 +0100352 /**
353 * Test LLDP output to controller.
354 */
355 @Test
356 public void lldpToController() {
357 StaticPacketTrace traceSuccess = mngr.trace(PACKET_LLDP, LLDP_FLOW_CP);
358 assertNotNull("Trace should not be null", traceSuccess);
359 assertTrue("Trace should be successful",
360 traceSuccess.resultMessage().contains("Packet goes to the controller"));
361 assertTrue("Master should be Master1",
362 traceSuccess.resultMessage().contains(MASTER_1));
363 ConnectPoint connectPoint = traceSuccess.getGroupOuputs(LLDP_FLOW_DEVICE).get(0).getOutput();
364 assertEquals("Packet Should go to CONTROLLER", PortNumber.CONTROLLER, connectPoint.port());
365 log.info("trace {}", traceSuccess.resultMessage());
366 }
367
Andrea Campanella04924b92018-01-17 16:34:51 +0100368 /**
369 * Test multicast in single device.
370 */
371 @Test
372 public void multicastTest() throws Exception {
373
374 StaticPacketTrace traceSuccess = mngr.trace(PACKET_OK_MULTICAST, MULTICAST_IN_CP);
375
376 log.info("trace {}", traceSuccess);
377
378 log.info("trace {}", traceSuccess.resultMessage());
379
380 assertNotNull("trace should not be null", traceSuccess);
381 assertEquals("Trace should have " + 2 + " output", 2,
382 traceSuccess.getGroupOuputs(MULTICAST_GROUP_FLOW_DEVICE).size());
383 assertEquals("Trace should only have " + 2 + "output", 2,
384 traceSuccess.getCompletePaths().size());
385 assertTrue("Trace should be successful",
386 traceSuccess.resultMessage().contains("reached output"));
387 assertEquals("Incorrect Output CP", MULTICAST_OUT_CP_2,
388 traceSuccess.getGroupOuputs(MULTICAST_GROUP_FLOW_DEVICE).get(0).getOutput());
389 assertEquals("Incorrect Output CP", MULTICAST_OUT_CP,
390 traceSuccess.getGroupOuputs(MULTICAST_GROUP_FLOW_DEVICE).get(1).getOutput());
391
392 }
393
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100394 /**
395 * Tests dual homing of a host.
396 */
397 @Test
398 public void dualhomedTest() throws Exception {
399 StaticPacketTrace traceSuccess = mngr.trace(PACKET_DUAL_HOME, DUAL_HOME_CP_1_1);
400
401 assertNotNull("trace should not be null", traceSuccess);
402 assertTrue("Should have 2 output paths", traceSuccess.getCompletePaths().size() == 2);
403 assertTrue("Should contain proper path", traceSuccess.getCompletePaths()
404 .contains(ImmutableList.of(DUAL_HOME_CP_1_1, DUAL_HOME_CP_1_2, DUAL_HOME_CP_2_1, DUAL_HOME_CP_2_2)));
405 assertTrue("Should contain proper path", traceSuccess.getCompletePaths()
406 .contains(ImmutableList.of(DUAL_HOME_CP_1_1, DUAL_HOME_CP_1_3, DUAL_HOME_CP_3_1, DUAL_HOME_CP_3_2)));
407
408 }
409
410
Andrea Campanella01e886e2017-12-15 15:27:31 +0100411 private StaticPacketTrace testSuccess(TrafficSelector packet, ConnectPoint in, DeviceId deviceId, ConnectPoint out,
Andrea Campanellae04aac92018-01-31 14:59:03 +0100412 int paths, int outputs) {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100413 StaticPacketTrace traceSuccess = mngr.trace(packet, in);
414
415 log.info("trace {}", traceSuccess);
416
417 log.info("trace {}", traceSuccess.resultMessage());
418
419 assertNotNull("trace should not be null", traceSuccess);
Andrea Campanellae04aac92018-01-31 14:59:03 +0100420 assertEquals("Trace should have " + outputs + " output", outputs,
421 traceSuccess.getGroupOuputs(deviceId).size());
Andrea Campanella01e886e2017-12-15 15:27:31 +0100422 assertEquals("Trace should only have " + paths + "output", paths, traceSuccess.getCompletePaths().size());
423 assertTrue("Trace should be successful",
424 traceSuccess.resultMessage().contains("Reached required destination Host"));
425 assertEquals("Incorrect Output CP", out,
426 traceSuccess.getGroupOuputs(deviceId).get(0).getOutput());
427
428 return traceSuccess;
429 }
430
Andrea Campanellae04aac92018-01-31 14:59:03 +0100431 private void testFailure(TrafficSelector packet, ConnectPoint in, DeviceId deviceId) {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100432 StaticPacketTrace traceFail = mngr.trace(packet, in);
433
434 log.info("trace {}", traceFail.resultMessage());
435
436 assertNotNull("Trace should not be null", traceFail);
437 assertNull("Trace should have 0 output", traceFail.getGroupOuputs(deviceId));
438 }
439
Seyeon Jeong357bcec2020-02-28 01:17:34 -0800440 private class TestFlowRuleService extends FlowNib {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100441 @Override
Andrea Campanellaa3369742018-04-13 12:14:48 +0200442 public Iterable<FlowEntry> getFlowEntriesByState(DeviceId deviceId, FlowEntry.FlowEntryState state) {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100443 if (deviceId.equals(SINGLE_FLOW_DEVICE)) {
444 return ImmutableList.of(SINGLE_FLOW_ENTRY);
445 } else if (deviceId.equals(DUAL_FLOW_DEVICE)) {
446 return ImmutableList.of(FIRST_FLOW_ENTRY, SECOND_FLOW_ENTRY);
447 } else if (deviceId.equals(GROUP_FLOW_DEVICE)) {
448 return ImmutableList.of(GROUP_FLOW_ENTRY);
449 } else if (deviceId.equals(TOPO_FLOW_DEVICE) ||
450 deviceId.equals(TOPO_FLOW_2_DEVICE) ||
451 deviceId.equals(TOPO_FLOW_3_DEVICE) ||
452 deviceId.equals(TOPO_FLOW_4_DEVICE)) {
453 return ImmutableList.of(TOPO_SINGLE_FLOW_ENTRY, TOPO_SECOND_INPUT_FLOW_ENTRY);
454 } else if (deviceId.equals(TOPO_GROUP_FLOW_DEVICE)) {
455 return ImmutableList.of(TOPO_GROUP_FLOW_ENTRY);
Andrea Campanella2bc55dd2018-01-18 16:54:34 +0100456 } else if (deviceId.equals(HARDWARE_DEVICE)) {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100457 return ImmutableList.of(HARDWARE_ETH_FLOW_ENTRY, HARDWARE_FLOW_ENTRY);
Andrea Campanellabb9d3fb2018-01-22 15:10:30 +0100458 } else if (deviceId.equals(SAME_OUTPUT_FLOW_DEVICE)) {
459 return ImmutableList.of(SAME_OUTPUT_FLOW_ENTRY);
Andrea Campanella7c8e7912018-01-23 12:46:04 +0100460 } else if (deviceId.equals(ARP_FLOW_DEVICE)) {
461 return ImmutableList.of(ARP_FLOW_ENTRY);
Andrea Campanellae04aac92018-01-31 14:59:03 +0100462 } else if (deviceId.equals(DUAL_LINK_1)) {
463 return ImmutableList.of(DUAL_LINK_1_GROUP_FLOW_ENTRY);
464 } else if (deviceId.equals(DUAL_LINK_2)) {
465 return ImmutableList.of(DUAL_LINK_1_GROUP_FLOW_ENTRY, DUAL_LINK_2_GROUP_FLOW_ENTRY);
466 } else if (deviceId.equals(DUAL_LINK_3)) {
467 return ImmutableList.of(DUAL_LINK_3_FLOW_ENTRY, DUAL_LINK_3_FLOW_ENTRY_2);
Andrea Campanellad5bb2ef2018-01-31 16:43:23 +0100468 } else if (deviceId.equals(DEFERRED_1)) {
469 return ImmutableList.of(DEFERRED_FLOW_ENTRY, DEFERRED_CLEAR_FLOW_ENTRY);
Andrea Campanella97f9d4c2018-02-06 18:58:40 +0100470 } else if (deviceId.equals(HARDWARE_DEVICE_10)) {
471 return ImmutableList.of(HARDWARE_10_FLOW_ENTRY, HARDWARE_10_SECOND_FLOW_ENTRY,
472 HARDWARE_10_OUTPUT_FLOW_ENTRY);
Andrea Campanella6f2d6742018-02-07 12:00:12 +0100473 } else if (deviceId.equals(LLDP_FLOW_DEVICE)) {
474 return ImmutableList.of(LLDP_FLOW_ENTRY);
Andrea Campanella04924b92018-01-17 16:34:51 +0100475 } else if (deviceId.equals(MULTICAST_GROUP_FLOW_DEVICE)) {
476 return ImmutableList.of(MULTICAST_GROUP_FLOW_ENTRY);
Andrea Campanella7cb4fd82018-02-27 12:36:00 +0100477 } else if (deviceId.equals(NO_BUCKET_DEVICE)) {
478 return ImmutableList.of(NO_BUCKET_ENTRY);
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100479 } else if (deviceId.equals(DUAL_HOME_DEVICE_1)) {
480 return ImmutableList.of(DUAL_HOME_FLOW_ENTRY);
481 } else if (deviceId.equals(DUAL_HOME_DEVICE_2) || deviceId.equals(DUAL_HOME_DEVICE_3)) {
482 return ImmutableList.of(DUAL_HOME_OUT_FLOW_ENTRY);
Seyeon Jeong351ed582020-04-07 12:06:18 -0700483 } else if (deviceId.equals(ACTION_ORDER_DEVICE)) {
484 return ImmutableList.of(ACTION_ORDER_FLOW_ENTRY);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100485 }
486 return ImmutableList.of();
487 }
488 }
489
Seyeon Jeong357bcec2020-02-28 01:17:34 -0800490 private class TestGroupService extends GroupNib {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100491 @Override
492 public Iterable<Group> getGroups(DeviceId deviceId) {
493 if (deviceId.equals(GROUP_FLOW_DEVICE)) {
494 return ImmutableList.of(GROUP);
495 } else if (deviceId.equals(TOPO_GROUP_FLOW_DEVICE)) {
496 return ImmutableList.of(TOPO_GROUP);
Andrea Campanellae04aac92018-01-31 14:59:03 +0100497 } else if (deviceId.equals(DUAL_LINK_1) || deviceId.equals(DUAL_LINK_2)) {
498 return ImmutableList.of(DUAL_LINK_GROUP);
Andrea Campanella04924b92018-01-17 16:34:51 +0100499 } else if (deviceId.equals(MULTICAST_GROUP_FLOW_DEVICE)) {
500 return ImmutableList.of(MULTICAST_GROUP);
Andrea Campanella7cb4fd82018-02-27 12:36:00 +0100501 } else if (deviceId.equals(NO_BUCKET_DEVICE)) {
502 return ImmutableList.of(NO_BUCKET_GROUP);
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100503 } else if (deviceId.equals(DUAL_HOME_DEVICE_1)) {
504 return ImmutableList.of(DUAL_HOME_GROUP);
Seyeon Jeong351ed582020-04-07 12:06:18 -0700505 } else if (deviceId.equals(ACTION_ORDER_DEVICE)) {
506 return ImmutableList.of(ACTION_ORDER_GROUP);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100507 }
508 return ImmutableList.of();
509 }
510 }
511
Seyeon Jeong357bcec2020-02-28 01:17:34 -0800512 private class TestHostService extends HostNib {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100513 @Override
514 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
515 if (connectPoint.equals(TOPO_FLOW_3_OUT_CP)) {
516 return ImmutableSet.of(H2);
Andrea Campanellae04aac92018-01-31 14:59:03 +0100517 } else if (connectPoint.equals(DUAL_LINK_1_CP_2_OUT) || connectPoint.equals(DUAL_LINK_1_CP_3_OUT) ||
518 connectPoint.equals(DUAL_LINK_2_CP_2_OUT) || connectPoint.equals(DUAL_LINK_2_CP_3_OUT)) {
519 return ImmutableSet.of();
Andrea Campanella01e886e2017-12-15 15:27:31 +0100520 }
Andrea Campanella04924b92018-01-17 16:34:51 +0100521 if (connectPoint.equals(SINGLE_FLOW_OUT_CP) ||
522 connectPoint.equals(DUAL_FLOW_OUT_CP) ||
523 connectPoint.equals(GROUP_FLOW_OUT_CP) ||
524 connectPoint.equals(HARDWARE_DEVICE_OUT_CP) ||
525 connectPoint.equals(HARDWARE_DEVICE_10_OUT_CP) ||
526 connectPoint.equals(DEFERRED_CP_2_OUT) ||
Seyeon Jeong351ed582020-04-07 12:06:18 -0700527 connectPoint.equals(DUAL_LINK_3_CP_3_OUT) ||
528 connectPoint.equals(ACTION_ORDER_OUT_CP)) {
Andrea Campanella04924b92018-01-17 16:34:51 +0100529 return ImmutableSet.of(H1);
530 }
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100531 if (connectPoint.equals(DUAL_HOME_CP_2_2) || connectPoint.equals(DUAL_HOME_CP_3_2)) {
532 return ImmutableSet.of(DUAL_HOME_H);
533 }
Andrea Campanella04924b92018-01-17 16:34:51 +0100534 return ImmutableSet.of();
Andrea Campanella01e886e2017-12-15 15:27:31 +0100535 }
536
537 @Override
538 public Set<Host> getHostsByMac(MacAddress mac) {
539 if (mac.equals(H1.mac())) {
540 return ImmutableSet.of(H1);
541 } else if (mac.equals(H2.mac())) {
542 return ImmutableSet.of(H2);
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100543 } else if (mac.equals(DUAL_HOME_H.mac())) {
544 return ImmutableSet.of(DUAL_HOME_H);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100545 }
546 return ImmutableSet.of();
547 }
548
549 @Override
550 public Set<Host> getHostsByIp(IpAddress ip) {
551 if ((H1.ipAddresses().contains(ip))) {
552 return ImmutableSet.of(H1);
553 } else if ((H2.ipAddresses().contains(ip))) {
554 return ImmutableSet.of(H2);
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100555 } else if ((DUAL_HOME_H.ipAddresses().contains(ip))) {
556 return ImmutableSet.of(DUAL_HOME_H);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100557 }
558 return ImmutableSet.of();
559 }
560 }
561
Seyeon Jeong357bcec2020-02-28 01:17:34 -0800562 private class TestLinkService extends LinkNib {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100563 @Override
564 public Set<Link> getEgressLinks(ConnectPoint connectPoint) {
565 if (connectPoint.equals(TOPO_FLOW_1_OUT_CP)
566 || connectPoint.equals(TOPO_FLOW_OUT_CP_1)) {
567 return ImmutableSet.of(DefaultLink.builder()
568 .providerId(ProviderId.NONE)
569 .type(Link.Type.DIRECT)
570 .src(connectPoint)
571 .dst(TOPO_FLOW_2_IN_CP)
572 .build());
573 } else if (connectPoint.equals(TOPO_FLOW_2_OUT_CP)) {
574 return ImmutableSet.of(DefaultLink.builder()
575 .providerId(ProviderId.NONE)
576 .type(Link.Type.DIRECT)
577 .src(TOPO_FLOW_2_OUT_CP)
578 .dst(TOPO_FLOW_3_IN_CP)
579 .build());
580 } else if (connectPoint.equals(TOPO_FLOW_OUT_CP_2)) {
581 return ImmutableSet.of(DefaultLink.builder()
582 .providerId(ProviderId.NONE)
583 .type(Link.Type.DIRECT)
584 .src(TOPO_FLOW_OUT_CP_2)
585 .dst(TOPO_FLOW_4_IN_CP)
586 .build());
587 } else if (connectPoint.equals(TOPO_FLOW_4_OUT_CP)) {
588 return ImmutableSet.of(DefaultLink.builder()
589 .providerId(ProviderId.NONE)
590 .type(Link.Type.DIRECT)
591 .src(TOPO_FLOW_4_OUT_CP)
592 .dst(TOPO_FLOW_3_IN_2_CP)
593 .build());
Andrea Campanellae04aac92018-01-31 14:59:03 +0100594 } else if (connectPoint.equals(DUAL_LINK_1_CP_2_OUT)) {
595 return ImmutableSet.of(DefaultLink.builder()
596 .providerId(ProviderId.NONE)
597 .type(Link.Type.DIRECT)
598 .src(DUAL_LINK_1_CP_2_OUT)
599 .dst(DUAL_LINK_2_CP_1_IN)
600 .build());
601 } else if (connectPoint.equals(DUAL_LINK_1_CP_3_OUT)) {
602 return ImmutableSet.of(DefaultLink.builder()
603 .providerId(ProviderId.NONE)
604 .type(Link.Type.DIRECT)
605 .src(DUAL_LINK_1_CP_3_OUT)
606 .dst(DUAL_LINK_2_CP_4_IN)
607 .build());
608 } else if (connectPoint.equals(DUAL_LINK_2_CP_2_OUT)) {
609 return ImmutableSet.of(DefaultLink.builder()
610 .providerId(ProviderId.NONE)
611 .type(Link.Type.DIRECT)
612 .src(DUAL_LINK_2_CP_2_OUT)
613 .dst(DUAL_LINK_3_CP_1_IN)
614 .build());
615 } else if (connectPoint.equals(DUAL_LINK_2_CP_3_OUT)) {
616 return ImmutableSet.of(DefaultLink.builder()
617 .providerId(ProviderId.NONE)
618 .type(Link.Type.DIRECT)
619 .src(DUAL_LINK_2_CP_3_OUT)
620 .dst(DUAL_LINK_3_CP_2_IN)
621 .build());
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100622 } else if (connectPoint.equals(DUAL_HOME_CP_1_2)) {
623 return ImmutableSet.of(DefaultLink.builder()
624 .providerId(ProviderId.NONE)
625 .type(Link.Type.DIRECT)
626 .src(DUAL_HOME_CP_1_2)
627 .dst(DUAL_HOME_CP_2_1)
628 .build());
629 } else if (connectPoint.equals(DUAL_HOME_CP_1_3)) {
630 return ImmutableSet.of(DefaultLink.builder()
631 .providerId(ProviderId.NONE)
632 .type(Link.Type.DIRECT)
633 .src(DUAL_HOME_CP_1_3)
634 .dst(DUAL_HOME_CP_3_1)
635 .build());
Andrea Campanella01e886e2017-12-15 15:27:31 +0100636 }
637 return ImmutableSet.of();
638 }
639 }
Andrea Campanella37d10622018-01-18 17:11:42 +0100640
Seyeon Jeong357bcec2020-02-28 01:17:34 -0800641 private class TestDeviceService extends DeviceNib {
Andrea Campanella37d10622018-01-18 17:11:42 +0100642 @Override
643 public Device getDevice(DeviceId deviceId) {
644 if (deviceId.equals(DeviceId.deviceId("nonexistent"))) {
645 return null;
646 }
647 return new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("test"), SWITCH,
648 "test", "test", "test", "test", new ChassisId(),
649 DefaultAnnotations.builder().set("foo", "bar").build());
650 }
651
652 @Override
Andrea Campanella04924b92018-01-17 16:34:51 +0100653 public Port getPort(ConnectPoint cp) {
654 return new DefaultPort(null, cp.port(), true, DefaultAnnotations.builder().build());
655 }
656
657 @Override
Andrea Campanella37d10622018-01-18 17:11:42 +0100658 public boolean isAvailable(DeviceId deviceId) {
Andrea Campanella04924b92018-01-17 16:34:51 +0100659 return !deviceId.equals(OFFLINE_DEVICE);
660 }
661 }
662
Seyeon Jeong357bcec2020-02-28 01:17:34 -0800663 private class TestDriverService extends DriverNib {
664 @Override
665 public String getDriverName(DeviceId deviceId) {
666 if (deviceId.equals(HARDWARE_DEVICE) || deviceId.equals(HARDWARE_DEVICE_10)) {
667 return "ofdpa";
668 }
669 return "NotHWDriver";
670 }
671 }
Andrea Campanella04924b92018-01-17 16:34:51 +0100672
Seyeon Jeong357bcec2020-02-28 01:17:34 -0800673 private class TestMastershipService extends MastershipNib {
674 @Override
675 public NodeId getMasterFor(DeviceId deviceId) {
676 return NodeId.nodeId(MASTER_1);
677 }
678 }
679
680 private class TestEdgePortService extends EdgePortNib {
Andrea Campanella04924b92018-01-17 16:34:51 +0100681 @Override
682 public boolean isEdgePoint(ConnectPoint point) {
683 return point.equals(MULTICAST_OUT_CP) ||
684 point.equals(MULTICAST_OUT_CP_2);
Andrea Campanella37d10622018-01-18 17:11:42 +0100685 }
686 }
Andrea Campanella7c8e7912018-01-23 12:46:04 +0100687
Seyeon Jeong357bcec2020-02-28 01:17:34 -0800688 private class TestRouteService extends RouteNib {
Andrea Campanellacc2424a2018-03-07 14:27:54 -0800689 @Override
690 public Optional<ResolvedRoute> longestPrefixLookup(IpAddress ip) {
691 return Optional.empty();
692 }
693 }
694
Andrea Campanella01e886e2017-12-15 15:27:31 +0100695}