blob: c00d37393798ba1a6e8415417558370ee3f50cca [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;
28import org.onosproject.mastership.MastershipServiceAdapter;
Andrea Campanella01e886e2017-12-15 15:27:31 +010029import org.onosproject.net.ConnectPoint;
Andrea Campanella37d10622018-01-18 17:11:42 +010030import org.onosproject.net.DefaultAnnotations;
31import org.onosproject.net.DefaultDevice;
Andrea Campanella01e886e2017-12-15 15:27:31 +010032import org.onosproject.net.DefaultLink;
Andrea Campanella04924b92018-01-17 16:34:51 +010033import org.onosproject.net.DefaultPort;
Andrea Campanella37d10622018-01-18 17:11:42 +010034import org.onosproject.net.Device;
Andrea Campanella01e886e2017-12-15 15:27:31 +010035import org.onosproject.net.DeviceId;
36import org.onosproject.net.Host;
37import org.onosproject.net.Link;
Andrea Campanella04924b92018-01-17 16:34:51 +010038import org.onosproject.net.Port;
Andrea Campanella7cb4fd82018-02-27 12:36:00 +010039import org.onosproject.net.PortNumber;
Andrea Campanella37d10622018-01-18 17:11:42 +010040import org.onosproject.net.device.DeviceServiceAdapter;
Andrea Campanella01e886e2017-12-15 15:27:31 +010041import org.onosproject.net.driver.DefaultDriver;
42import org.onosproject.net.driver.Driver;
43import org.onosproject.net.driver.DriverServiceAdapter;
Andrea Campanella04924b92018-01-17 16:34:51 +010044import org.onosproject.net.edge.EdgePortServiceAdapter;
Andrea Campanella01e886e2017-12-15 15:27:31 +010045import org.onosproject.net.flow.FlowEntry;
46import org.onosproject.net.flow.FlowRuleServiceAdapter;
47import org.onosproject.net.flow.TrafficSelector;
48import org.onosproject.net.flow.criteria.Criterion;
49import org.onosproject.net.flow.criteria.EthTypeCriterion;
Seyeon Jeong351ed582020-04-07 12:06:18 -070050import org.onosproject.net.flow.criteria.MplsCriterion;
Andrea Campanella01e886e2017-12-15 15:27:31 +010051import org.onosproject.net.flow.criteria.VlanIdCriterion;
52import org.onosproject.net.group.Group;
53import org.onosproject.net.group.GroupServiceAdapter;
54import org.onosproject.net.host.HostServiceAdapter;
55import org.onosproject.net.link.LinkServiceAdapter;
56import org.onosproject.net.provider.ProviderId;
Andrea Campanellacc2424a2018-03-07 14:27:54 -080057import org.onosproject.routeservice.ResolvedRoute;
58import org.onosproject.routeservice.RouteServiceAdapter;
Andrea Campanella01e886e2017-12-15 15:27:31 +010059import org.onosproject.t3.api.StaticPacketTrace;
60import org.slf4j.Logger;
61
62import java.util.HashMap;
Andrea Campanellacc2424a2018-03-07 14:27:54 -080063import java.util.Optional;
Andrea Campanella01e886e2017-12-15 15:27:31 +010064import java.util.Set;
65
66import static org.junit.Assert.assertEquals;
67import static org.junit.Assert.assertNotNull;
68import static org.junit.Assert.assertNull;
69import static org.junit.Assert.assertTrue;
Andrea Campanella37d10622018-01-18 17:11:42 +010070import static org.onosproject.net.Device.Type.SWITCH;
Andrea Campanella01e886e2017-12-15 15:27:31 +010071import static org.onosproject.t3.impl.T3TestObjects.*;
Andrea Campanella6f2d6742018-02-07 12:00:12 +010072import static org.onosproject.t3.impl.TroubleshootManager.PACKET_TO_CONTROLLER;
Andrea Campanella01e886e2017-12-15 15:27:31 +010073import static org.slf4j.LoggerFactory.getLogger;
74
75/**
76 * Test Class for Troubleshoot Manager.
77 */
78public class TroubleshootManagerTest {
79
80 private static final Logger log = getLogger(TroubleshootManager.class);
81
82 private TroubleshootManager mngr;
83
84 @Before
85 public void setUp() throws Exception {
86 mngr = new TroubleshootManager();
87 mngr.flowRuleService = new TestFlowRuleService();
88 mngr.hostService = new TestHostService();
89 mngr.linkService = new TestLinkService();
90 mngr.driverService = new TestDriverService();
91 mngr.groupService = new TestGroupService();
Andrea Campanella37d10622018-01-18 17:11:42 +010092 mngr.deviceService = new TestDeviceService();
Andrea Campanella7c8e7912018-01-23 12:46:04 +010093 mngr.mastershipService = new TestMastershipService();
Andrea Campanella04924b92018-01-17 16:34:51 +010094 mngr.edgePortService = new TestEdgePortService();
Andrea Campanellacc2424a2018-03-07 14:27:54 -080095 mngr.routeService = new TestRouteService();
Andrea Campanella01e886e2017-12-15 15:27:31 +010096
97 assertNotNull("Manager should not be null", mngr);
98
99 assertNotNull("Flow rule Service should not be null", mngr.flowRuleService);
100 assertNotNull("Host Service should not be null", mngr.hostService);
101 assertNotNull("Group Service should not be null", mngr.groupService);
102 assertNotNull("Driver Service should not be null", mngr.driverService);
103 assertNotNull("Link Service should not be null", mngr.linkService);
Andrea Campanella37d10622018-01-18 17:11:42 +0100104 assertNotNull("Device Service should not be null", mngr.deviceService);
105 }
106
107 /**
108 * Tests failure on non existent device.
109 */
110 @Test(expected = NullPointerException.class)
111 public void nonExistentDevice() {
112 StaticPacketTrace traceFail = mngr.trace(PACKET_OK, ConnectPoint.deviceConnectPoint("nonexistent" + "/1"));
113 }
114
115 /**
116 * Tests failure on offline device.
117 */
118 @Test
119 public void offlineDevice() {
120 StaticPacketTrace traceFail = mngr.trace(PACKET_OK, ConnectPoint.deviceConnectPoint(OFFLINE_DEVICE + "/1"));
121 assertNotNull("Trace should not be null", traceFail);
122 assertNull("Trace should have 0 output", traceFail.getGroupOuputs(SINGLE_FLOW_DEVICE));
Andrea Campanellabb9d3fb2018-01-22 15:10:30 +0100123 }
124
125 /**
126 * Tests failure on same output.
127 */
128 @Test
129 public void sameOutput() {
130 StaticPacketTrace traceFail = mngr.trace(PACKET_OK, SAME_OUTPUT_FLOW_CP);
131 assertNotNull("Trace should not be null", traceFail);
132 assertTrue("Trace should be unsuccessful",
133 traceFail.resultMessage().contains("is same as initial input"));
Andrea Campanella37d10622018-01-18 17:11:42 +0100134 log.info("trace {}", traceFail.resultMessage());
Andrea Campanella01e886e2017-12-15 15:27:31 +0100135 }
136
Andrea Campanella7c8e7912018-01-23 12:46:04 +0100137 /**
138 * Tests ARP to controller.
139 */
140 @Test
141 public void arpToController() {
142 StaticPacketTrace traceSuccess = mngr.trace(PACKET_ARP, ARP_FLOW_CP);
143 assertNotNull("Trace should not be null", traceSuccess);
144 assertTrue("Trace should be successful",
Andrea Campanella6f2d6742018-02-07 12:00:12 +0100145 traceSuccess.resultMessage().contains(PACKET_TO_CONTROLLER));
Andrea Campanella7c8e7912018-01-23 12:46:04 +0100146 assertTrue("Master should be Master1",
147 traceSuccess.resultMessage().contains(MASTER_1));
148 ConnectPoint connectPoint = traceSuccess.getGroupOuputs(ARP_FLOW_DEVICE).get(0).getOutput();
149 assertEquals("Packet Should go to CONTROLLER", PortNumber.CONTROLLER, connectPoint.port());
Andrea Campanella58b3b522018-02-06 15:46:52 +0100150 assertNull("VlanId should be null", traceSuccess.getGroupOuputs(ARP_FLOW_DEVICE).get(0)
151 .getFinalPacket().getCriterion(Criterion.Type.VLAN_VID));
Andrea Campanella7c8e7912018-01-23 12:46:04 +0100152 log.info("trace {}", traceSuccess.resultMessage());
153 }
154
Andrea Campanellabb9d3fb2018-01-22 15:10:30 +0100155
Andrea Campanella01e886e2017-12-15 15:27:31 +0100156 /**
Andrea Campanella2bc55dd2018-01-18 16:54:34 +0100157 * Tests failure on device with no flows.
Andrea Campanella01e886e2017-12-15 15:27:31 +0100158 */
159 @Test
160 public void noFlows() {
161 StaticPacketTrace traceFail = mngr.trace(PACKET_OK, ConnectPoint.deviceConnectPoint("test/1"));
162 assertNotNull("Trace should not be null", traceFail);
163 assertNull("Trace should have 0 output", traceFail.getGroupOuputs(SINGLE_FLOW_DEVICE));
164 log.info("trace {}", traceFail.resultMessage());
165 }
166
167 /**
Andrea Campanella7cb4fd82018-02-27 12:36:00 +0100168 * Test group with no buckets.
169 */
170 @Test
171 public void noBucketsTest() throws Exception {
172
173 StaticPacketTrace traceFail = mngr.trace(PACKET_OK, NO_BUCKET_CP);
174 assertNotNull("Trace should not be null", traceFail);
175 assertTrue("Trace should be unsuccessful",
176 traceFail.resultMessage().contains("no buckets"));
177 log.info("trace {}", traceFail.resultMessage());
178
179 }
180
181 /**
Andrea Campanella01e886e2017-12-15 15:27:31 +0100182 * Test a single flow rule that has output port in it.
183 */
184 @Test
185 public void testSingleFlowRule() {
186
Andrea Campanellae04aac92018-01-31 14:59:03 +0100187 testSuccess(PACKET_OK, SINGLE_FLOW_IN_CP, SINGLE_FLOW_DEVICE, SINGLE_FLOW_OUT_CP, 1, 1);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100188
Andrea Campanellae04aac92018-01-31 14:59:03 +0100189 testFailure(PACKET_FAIL, SINGLE_FLOW_IN_CP, SINGLE_FLOW_DEVICE);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100190 }
191
192 /**
193 * Tests two flow rule the last one of which has output port in it.
194 */
195 @Test
196 public void testDualFlowRule() {
197
198 //Test Success
199
Andrea Campanella2bc55dd2018-01-18 16:54:34 +0100200 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, DUAL_FLOW_IN_CP, DUAL_FLOW_DEVICE,
Andrea Campanellae04aac92018-01-31 14:59:03 +0100201 DUAL_FLOW_OUT_CP, 1, 1);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100202
203 //Testing Vlan
204 Criterion criterion = traceSuccess.getGroupOuputs(DUAL_FLOW_DEVICE).get(0).
205 getFinalPacket().getCriterion(Criterion.Type.VLAN_VID);
206 assertNotNull("Packet Should have Vlan", criterion);
207
208 VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) criterion;
209
210 assertEquals("Vlan should be 100", VlanId.vlanId((short) 100), vlanIdCriterion.vlanId());
211
212 //Test Faliure
Andrea Campanellae04aac92018-01-31 14:59:03 +0100213 testFailure(PACKET_FAIL, DUAL_FLOW_IN_CP, DUAL_FLOW_DEVICE);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100214
215 }
216
217 /**
218 * Test a single flow rule that points to a group with output port in it.
219 */
220 @Test
221 public void flowAndGroup() throws Exception {
222
Andrea Campanella2bc55dd2018-01-18 16:54:34 +0100223 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, GROUP_FLOW_IN_CP, GROUP_FLOW_DEVICE,
Andrea Campanellae04aac92018-01-31 14:59:03 +0100224 GROUP_FLOW_OUT_CP, 1, 1);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100225
226 assertTrue("Wrong Output Group", traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
227 .get(0).getGroups().contains(GROUP));
Andrea Campanella09ca07a2018-01-25 16:44:04 +0100228 assertEquals("Packet should not have MPLS Label", EthType.EtherType.IPV4.ethType(),
229 ((EthTypeCriterion) traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
230 .get(0).getFinalPacket().getCriterion(Criterion.Type.ETH_TYPE)).ethType());
231 assertNull("Packet should not have MPLS Label", traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
232 .get(0).getFinalPacket().getCriterion(Criterion.Type.MPLS_LABEL));
233 assertNull("Packet should not have MPLS Label", traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
234 .get(0).getFinalPacket().getCriterion(Criterion.Type.MPLS_BOS));
Andrea Campanella01e886e2017-12-15 15:27:31 +0100235
236 }
237
238 /**
Seyeon Jeong351ed582020-04-07 12:06:18 -0700239 * Test a single flow rule that points to a group with multiple actions
240 * that need to be executed in the order specified in the OpenFlow spec.
241 */
242 @Test
243 public void testGroupMultipleActionsOrdered() {
244
245 StaticPacketTrace traceSuccess = testSuccess(
246 PACKET_OK, ACTION_ORDER_IN_CP, ACTION_ORDER_DEVICE, ACTION_ORDER_OUT_CP, 1, 1);
247
248 assertEquals("Packet should not have VLAN ID",
249 VlanId.NONE,
250 ((VlanIdCriterion) traceSuccess.getGroupOuputs(ACTION_ORDER_DEVICE)
251 .get(0).getFinalPacket().getCriterion(Criterion.Type.VLAN_VID)).vlanId());
252 assertEquals("Packet should have MPLS label",
253 ACTION_ORDER_MPLS_LABEL,
254 ((MplsCriterion) traceSuccess.getGroupOuputs(ACTION_ORDER_DEVICE)
255 .get(0).getFinalPacket().getCriterion(Criterion.Type.MPLS_LABEL)).label());
256
257 }
258
259 /**
Andrea Campanella01e886e2017-12-15 15:27:31 +0100260 * Test path through a 3 device topology.
261 */
262 @Test
263 public void singlePathTopology() throws Exception {
264
265 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK_TOPO, TOPO_FLOW_1_IN_CP,
Andrea Campanellae04aac92018-01-31 14:59:03 +0100266 TOPO_FLOW_3_DEVICE, TOPO_FLOW_3_OUT_CP, 1, 1);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100267
268 assertTrue("Incorrect path",
269 traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_2_IN_CP));
270 assertTrue("Incorrect path",
271 traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_2_OUT_CP));
272 assertTrue("Incorrect path",
273 traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_3_IN_CP));
274
275 }
276
277 /**
278 * Test path through a 4 device topology with first device that has groups with multiple output buckets.
279 */
280 @Test
281 public void testGroupTopo() throws Exception {
282
283 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK_TOPO, TOPO_FLOW_IN_CP,
Andrea Campanellae04aac92018-01-31 14:59:03 +0100284 TOPO_FLOW_3_DEVICE, TOPO_FLOW_3_OUT_CP, 2, 1);
285
286 log.info("{}", traceSuccess);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100287
288 assertTrue("Incorrect groups",
289 traceSuccess.getGroupOuputs(TOPO_GROUP_FLOW_DEVICE).get(0).getGroups().contains(TOPO_GROUP));
290 assertTrue("Incorrect bucket",
291 traceSuccess.getGroupOuputs(TOPO_GROUP_FLOW_DEVICE).get(1).getGroups().contains(TOPO_GROUP));
292 }
293
294 /**
295 * Test HW support in a single device with 2 flow rules to check hit of static HW rules.
296 */
297 @Test
298 public void hardwareTest() throws Exception {
299
300 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, HARDWARE_DEVICE_IN_CP,
Andrea Campanellae04aac92018-01-31 14:59:03 +0100301 HARDWARE_DEVICE, HARDWARE_DEVICE_OUT_CP, 1, 1);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100302
303 assertEquals("wrong ETH type", EthType.EtherType.IPV4.ethType(),
304 ((EthTypeCriterion) traceSuccess.getGroupOuputs(HARDWARE_DEVICE).get(0).getFinalPacket()
305 .getCriterion(Criterion.Type.ETH_TYPE)).ethType());
306
307 }
308
Andrea Campanellae04aac92018-01-31 14:59:03 +0100309 /**
Andrea Campanella97f9d4c2018-02-06 18:58:40 +0100310 * Test that HW has two rules on table 10 for untagged packets.
311 */
312 @Test
313 public void hardwareTable10Test() throws Exception {
314
315 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, HARDWARE_DEVICE_10_IN_CP,
316 HARDWARE_DEVICE_10, HARDWARE_DEVICE_10_OUT_CP, 1, 1);
317
318 assertTrue("Second flow rule is absent", traceSuccess.getFlowsForDevice(HARDWARE_DEVICE_10)
319 .contains(HARDWARE_10_SECOND_FLOW_ENTRY));
320
321 }
322
323 /**
Andrea Campanellae04aac92018-01-31 14:59:03 +0100324 * Test dual links between 3 topology elements.
325 */
326 @Test
327 public void dualLinks() throws Exception {
328
329 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, DUAL_LINK_1_CP_1_IN,
330 DUAL_LINK_3, DUAL_LINK_3_CP_3_OUT, 4, 1);
331
332 //TODO tests
333
334 }
335
Andrea Campanellad5bb2ef2018-01-31 16:43:23 +0100336 /**
337 * Test proper clear deferred behaviour.
338 */
339 @Test
340 public void clearDeferred() throws Exception {
341
342 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, DEFERRED_CP_1_IN,
343 DEFERRED_1, DEFERRED_CP_2_OUT, 1, 1);
344
345 assertNull("MPLS should have been not applied due to clear deferred", traceSuccess
346 .getGroupOuputs(DEFERRED_1).get(0).getFinalPacket().getCriterion(Criterion.Type.MPLS_LABEL));
347
348 }
349
350
Andrea Campanella6f2d6742018-02-07 12:00:12 +0100351 /**
352 * Test LLDP output to controller.
353 */
354 @Test
355 public void lldpToController() {
356 StaticPacketTrace traceSuccess = mngr.trace(PACKET_LLDP, LLDP_FLOW_CP);
357 assertNotNull("Trace should not be null", traceSuccess);
358 assertTrue("Trace should be successful",
359 traceSuccess.resultMessage().contains("Packet goes to the controller"));
360 assertTrue("Master should be Master1",
361 traceSuccess.resultMessage().contains(MASTER_1));
362 ConnectPoint connectPoint = traceSuccess.getGroupOuputs(LLDP_FLOW_DEVICE).get(0).getOutput();
363 assertEquals("Packet Should go to CONTROLLER", PortNumber.CONTROLLER, connectPoint.port());
364 log.info("trace {}", traceSuccess.resultMessage());
365 }
366
Andrea Campanella04924b92018-01-17 16:34:51 +0100367 /**
368 * Test multicast in single device.
369 */
370 @Test
371 public void multicastTest() throws Exception {
372
373 StaticPacketTrace traceSuccess = mngr.trace(PACKET_OK_MULTICAST, MULTICAST_IN_CP);
374
375 log.info("trace {}", traceSuccess);
376
377 log.info("trace {}", traceSuccess.resultMessage());
378
379 assertNotNull("trace should not be null", traceSuccess);
380 assertEquals("Trace should have " + 2 + " output", 2,
381 traceSuccess.getGroupOuputs(MULTICAST_GROUP_FLOW_DEVICE).size());
382 assertEquals("Trace should only have " + 2 + "output", 2,
383 traceSuccess.getCompletePaths().size());
384 assertTrue("Trace should be successful",
385 traceSuccess.resultMessage().contains("reached output"));
386 assertEquals("Incorrect Output CP", MULTICAST_OUT_CP_2,
387 traceSuccess.getGroupOuputs(MULTICAST_GROUP_FLOW_DEVICE).get(0).getOutput());
388 assertEquals("Incorrect Output CP", MULTICAST_OUT_CP,
389 traceSuccess.getGroupOuputs(MULTICAST_GROUP_FLOW_DEVICE).get(1).getOutput());
390
391 }
392
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100393 /**
394 * Tests dual homing of a host.
395 */
396 @Test
397 public void dualhomedTest() throws Exception {
398 StaticPacketTrace traceSuccess = mngr.trace(PACKET_DUAL_HOME, DUAL_HOME_CP_1_1);
399
400 assertNotNull("trace should not be null", traceSuccess);
401 assertTrue("Should have 2 output paths", traceSuccess.getCompletePaths().size() == 2);
402 assertTrue("Should contain proper path", traceSuccess.getCompletePaths()
403 .contains(ImmutableList.of(DUAL_HOME_CP_1_1, DUAL_HOME_CP_1_2, DUAL_HOME_CP_2_1, DUAL_HOME_CP_2_2)));
404 assertTrue("Should contain proper path", traceSuccess.getCompletePaths()
405 .contains(ImmutableList.of(DUAL_HOME_CP_1_1, DUAL_HOME_CP_1_3, DUAL_HOME_CP_3_1, DUAL_HOME_CP_3_2)));
406
407 }
408
409
Andrea Campanella01e886e2017-12-15 15:27:31 +0100410 private StaticPacketTrace testSuccess(TrafficSelector packet, ConnectPoint in, DeviceId deviceId, ConnectPoint out,
Andrea Campanellae04aac92018-01-31 14:59:03 +0100411 int paths, int outputs) {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100412 StaticPacketTrace traceSuccess = mngr.trace(packet, in);
413
414 log.info("trace {}", traceSuccess);
415
416 log.info("trace {}", traceSuccess.resultMessage());
417
418 assertNotNull("trace should not be null", traceSuccess);
Andrea Campanellae04aac92018-01-31 14:59:03 +0100419 assertEquals("Trace should have " + outputs + " output", outputs,
420 traceSuccess.getGroupOuputs(deviceId).size());
Andrea Campanella01e886e2017-12-15 15:27:31 +0100421 assertEquals("Trace should only have " + paths + "output", paths, traceSuccess.getCompletePaths().size());
422 assertTrue("Trace should be successful",
423 traceSuccess.resultMessage().contains("Reached required destination Host"));
424 assertEquals("Incorrect Output CP", out,
425 traceSuccess.getGroupOuputs(deviceId).get(0).getOutput());
426
427 return traceSuccess;
428 }
429
Andrea Campanellae04aac92018-01-31 14:59:03 +0100430 private void testFailure(TrafficSelector packet, ConnectPoint in, DeviceId deviceId) {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100431 StaticPacketTrace traceFail = mngr.trace(packet, in);
432
433 log.info("trace {}", traceFail.resultMessage());
434
435 assertNotNull("Trace should not be null", traceFail);
436 assertNull("Trace should have 0 output", traceFail.getGroupOuputs(deviceId));
437 }
438
439 private class TestFlowRuleService extends FlowRuleServiceAdapter {
440 @Override
Andrea Campanellaa3369742018-04-13 12:14:48 +0200441 public Iterable<FlowEntry> getFlowEntriesByState(DeviceId deviceId, FlowEntry.FlowEntryState state) {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100442 if (deviceId.equals(SINGLE_FLOW_DEVICE)) {
443 return ImmutableList.of(SINGLE_FLOW_ENTRY);
444 } else if (deviceId.equals(DUAL_FLOW_DEVICE)) {
445 return ImmutableList.of(FIRST_FLOW_ENTRY, SECOND_FLOW_ENTRY);
446 } else if (deviceId.equals(GROUP_FLOW_DEVICE)) {
447 return ImmutableList.of(GROUP_FLOW_ENTRY);
448 } else if (deviceId.equals(TOPO_FLOW_DEVICE) ||
449 deviceId.equals(TOPO_FLOW_2_DEVICE) ||
450 deviceId.equals(TOPO_FLOW_3_DEVICE) ||
451 deviceId.equals(TOPO_FLOW_4_DEVICE)) {
452 return ImmutableList.of(TOPO_SINGLE_FLOW_ENTRY, TOPO_SECOND_INPUT_FLOW_ENTRY);
453 } else if (deviceId.equals(TOPO_GROUP_FLOW_DEVICE)) {
454 return ImmutableList.of(TOPO_GROUP_FLOW_ENTRY);
Andrea Campanella2bc55dd2018-01-18 16:54:34 +0100455 } else if (deviceId.equals(HARDWARE_DEVICE)) {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100456 return ImmutableList.of(HARDWARE_ETH_FLOW_ENTRY, HARDWARE_FLOW_ENTRY);
Andrea Campanellabb9d3fb2018-01-22 15:10:30 +0100457 } else if (deviceId.equals(SAME_OUTPUT_FLOW_DEVICE)) {
458 return ImmutableList.of(SAME_OUTPUT_FLOW_ENTRY);
Andrea Campanella7c8e7912018-01-23 12:46:04 +0100459 } else if (deviceId.equals(ARP_FLOW_DEVICE)) {
460 return ImmutableList.of(ARP_FLOW_ENTRY);
Andrea Campanellae04aac92018-01-31 14:59:03 +0100461 } else if (deviceId.equals(DUAL_LINK_1)) {
462 return ImmutableList.of(DUAL_LINK_1_GROUP_FLOW_ENTRY);
463 } else if (deviceId.equals(DUAL_LINK_2)) {
464 return ImmutableList.of(DUAL_LINK_1_GROUP_FLOW_ENTRY, DUAL_LINK_2_GROUP_FLOW_ENTRY);
465 } else if (deviceId.equals(DUAL_LINK_3)) {
466 return ImmutableList.of(DUAL_LINK_3_FLOW_ENTRY, DUAL_LINK_3_FLOW_ENTRY_2);
Andrea Campanellad5bb2ef2018-01-31 16:43:23 +0100467 } else if (deviceId.equals(DEFERRED_1)) {
468 return ImmutableList.of(DEFERRED_FLOW_ENTRY, DEFERRED_CLEAR_FLOW_ENTRY);
Andrea Campanella97f9d4c2018-02-06 18:58:40 +0100469 } else if (deviceId.equals(HARDWARE_DEVICE_10)) {
470 return ImmutableList.of(HARDWARE_10_FLOW_ENTRY, HARDWARE_10_SECOND_FLOW_ENTRY,
471 HARDWARE_10_OUTPUT_FLOW_ENTRY);
Andrea Campanella6f2d6742018-02-07 12:00:12 +0100472 } else if (deviceId.equals(LLDP_FLOW_DEVICE)) {
473 return ImmutableList.of(LLDP_FLOW_ENTRY);
Andrea Campanella04924b92018-01-17 16:34:51 +0100474 } else if (deviceId.equals(MULTICAST_GROUP_FLOW_DEVICE)) {
475 return ImmutableList.of(MULTICAST_GROUP_FLOW_ENTRY);
Andrea Campanella7cb4fd82018-02-27 12:36:00 +0100476 } else if (deviceId.equals(NO_BUCKET_DEVICE)) {
477 return ImmutableList.of(NO_BUCKET_ENTRY);
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100478 } else if (deviceId.equals(DUAL_HOME_DEVICE_1)) {
479 return ImmutableList.of(DUAL_HOME_FLOW_ENTRY);
480 } else if (deviceId.equals(DUAL_HOME_DEVICE_2) || deviceId.equals(DUAL_HOME_DEVICE_3)) {
481 return ImmutableList.of(DUAL_HOME_OUT_FLOW_ENTRY);
Seyeon Jeong351ed582020-04-07 12:06:18 -0700482 } else if (deviceId.equals(ACTION_ORDER_DEVICE)) {
483 return ImmutableList.of(ACTION_ORDER_FLOW_ENTRY);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100484 }
485 return ImmutableList.of();
486 }
487 }
488
489 private class TestDriverService extends DriverServiceAdapter {
490 @Override
491 public Driver getDriver(DeviceId deviceId) {
Andrea Campanella97f9d4c2018-02-06 18:58:40 +0100492 if (deviceId.equals(HARDWARE_DEVICE) || deviceId.equals(HARDWARE_DEVICE_10)) {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100493 return new DefaultDriver("ofdpa", ImmutableList.of(),
494 "test", "test", "test", new HashMap<>(), new HashMap<>());
495 }
496 return new DefaultDriver("NotHWDriver", ImmutableList.of(),
497 "test", "test", "test", new HashMap<>(), new HashMap<>());
498 }
499 }
500
501 private class TestGroupService extends GroupServiceAdapter {
502 @Override
503 public Iterable<Group> getGroups(DeviceId deviceId) {
504 if (deviceId.equals(GROUP_FLOW_DEVICE)) {
505 return ImmutableList.of(GROUP);
506 } else if (deviceId.equals(TOPO_GROUP_FLOW_DEVICE)) {
507 return ImmutableList.of(TOPO_GROUP);
Andrea Campanellae04aac92018-01-31 14:59:03 +0100508 } else if (deviceId.equals(DUAL_LINK_1) || deviceId.equals(DUAL_LINK_2)) {
509 return ImmutableList.of(DUAL_LINK_GROUP);
Andrea Campanella04924b92018-01-17 16:34:51 +0100510 } else if (deviceId.equals(MULTICAST_GROUP_FLOW_DEVICE)) {
511 return ImmutableList.of(MULTICAST_GROUP);
Andrea Campanella7cb4fd82018-02-27 12:36:00 +0100512 } else if (deviceId.equals(NO_BUCKET_DEVICE)) {
513 return ImmutableList.of(NO_BUCKET_GROUP);
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100514 } else if (deviceId.equals(DUAL_HOME_DEVICE_1)) {
515 return ImmutableList.of(DUAL_HOME_GROUP);
Seyeon Jeong351ed582020-04-07 12:06:18 -0700516 } else if (deviceId.equals(ACTION_ORDER_DEVICE)) {
517 return ImmutableList.of(ACTION_ORDER_GROUP);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100518 }
519 return ImmutableList.of();
520 }
521 }
522
523 private class TestHostService extends HostServiceAdapter {
524 @Override
525 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
526 if (connectPoint.equals(TOPO_FLOW_3_OUT_CP)) {
527 return ImmutableSet.of(H2);
Andrea Campanellae04aac92018-01-31 14:59:03 +0100528 } else if (connectPoint.equals(DUAL_LINK_1_CP_2_OUT) || connectPoint.equals(DUAL_LINK_1_CP_3_OUT) ||
529 connectPoint.equals(DUAL_LINK_2_CP_2_OUT) || connectPoint.equals(DUAL_LINK_2_CP_3_OUT)) {
530 return ImmutableSet.of();
Andrea Campanella01e886e2017-12-15 15:27:31 +0100531 }
Andrea Campanella04924b92018-01-17 16:34:51 +0100532 if (connectPoint.equals(SINGLE_FLOW_OUT_CP) ||
533 connectPoint.equals(DUAL_FLOW_OUT_CP) ||
534 connectPoint.equals(GROUP_FLOW_OUT_CP) ||
535 connectPoint.equals(HARDWARE_DEVICE_OUT_CP) ||
536 connectPoint.equals(HARDWARE_DEVICE_10_OUT_CP) ||
537 connectPoint.equals(DEFERRED_CP_2_OUT) ||
Seyeon Jeong351ed582020-04-07 12:06:18 -0700538 connectPoint.equals(DUAL_LINK_3_CP_3_OUT) ||
539 connectPoint.equals(ACTION_ORDER_OUT_CP)) {
Andrea Campanella04924b92018-01-17 16:34:51 +0100540 return ImmutableSet.of(H1);
541 }
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100542 if (connectPoint.equals(DUAL_HOME_CP_2_2) || connectPoint.equals(DUAL_HOME_CP_3_2)) {
543 return ImmutableSet.of(DUAL_HOME_H);
544 }
Andrea Campanella04924b92018-01-17 16:34:51 +0100545 return ImmutableSet.of();
Andrea Campanella01e886e2017-12-15 15:27:31 +0100546 }
547
548 @Override
549 public Set<Host> getHostsByMac(MacAddress mac) {
550 if (mac.equals(H1.mac())) {
551 return ImmutableSet.of(H1);
552 } else if (mac.equals(H2.mac())) {
553 return ImmutableSet.of(H2);
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100554 } else if (mac.equals(DUAL_HOME_H.mac())) {
555 return ImmutableSet.of(DUAL_HOME_H);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100556 }
557 return ImmutableSet.of();
558 }
559
560 @Override
561 public Set<Host> getHostsByIp(IpAddress ip) {
562 if ((H1.ipAddresses().contains(ip))) {
563 return ImmutableSet.of(H1);
564 } else if ((H2.ipAddresses().contains(ip))) {
565 return ImmutableSet.of(H2);
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100566 } else if ((DUAL_HOME_H.ipAddresses().contains(ip))) {
567 return ImmutableSet.of(DUAL_HOME_H);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100568 }
569 return ImmutableSet.of();
570 }
571 }
572
573 private class TestLinkService extends LinkServiceAdapter {
574 @Override
575 public Set<Link> getEgressLinks(ConnectPoint connectPoint) {
576 if (connectPoint.equals(TOPO_FLOW_1_OUT_CP)
577 || connectPoint.equals(TOPO_FLOW_OUT_CP_1)) {
578 return ImmutableSet.of(DefaultLink.builder()
579 .providerId(ProviderId.NONE)
580 .type(Link.Type.DIRECT)
581 .src(connectPoint)
582 .dst(TOPO_FLOW_2_IN_CP)
583 .build());
584 } else if (connectPoint.equals(TOPO_FLOW_2_OUT_CP)) {
585 return ImmutableSet.of(DefaultLink.builder()
586 .providerId(ProviderId.NONE)
587 .type(Link.Type.DIRECT)
588 .src(TOPO_FLOW_2_OUT_CP)
589 .dst(TOPO_FLOW_3_IN_CP)
590 .build());
591 } else if (connectPoint.equals(TOPO_FLOW_OUT_CP_2)) {
592 return ImmutableSet.of(DefaultLink.builder()
593 .providerId(ProviderId.NONE)
594 .type(Link.Type.DIRECT)
595 .src(TOPO_FLOW_OUT_CP_2)
596 .dst(TOPO_FLOW_4_IN_CP)
597 .build());
598 } else if (connectPoint.equals(TOPO_FLOW_4_OUT_CP)) {
599 return ImmutableSet.of(DefaultLink.builder()
600 .providerId(ProviderId.NONE)
601 .type(Link.Type.DIRECT)
602 .src(TOPO_FLOW_4_OUT_CP)
603 .dst(TOPO_FLOW_3_IN_2_CP)
604 .build());
Andrea Campanellae04aac92018-01-31 14:59:03 +0100605 } else if (connectPoint.equals(DUAL_LINK_1_CP_2_OUT)) {
606 return ImmutableSet.of(DefaultLink.builder()
607 .providerId(ProviderId.NONE)
608 .type(Link.Type.DIRECT)
609 .src(DUAL_LINK_1_CP_2_OUT)
610 .dst(DUAL_LINK_2_CP_1_IN)
611 .build());
612 } else if (connectPoint.equals(DUAL_LINK_1_CP_3_OUT)) {
613 return ImmutableSet.of(DefaultLink.builder()
614 .providerId(ProviderId.NONE)
615 .type(Link.Type.DIRECT)
616 .src(DUAL_LINK_1_CP_3_OUT)
617 .dst(DUAL_LINK_2_CP_4_IN)
618 .build());
619 } else if (connectPoint.equals(DUAL_LINK_2_CP_2_OUT)) {
620 return ImmutableSet.of(DefaultLink.builder()
621 .providerId(ProviderId.NONE)
622 .type(Link.Type.DIRECT)
623 .src(DUAL_LINK_2_CP_2_OUT)
624 .dst(DUAL_LINK_3_CP_1_IN)
625 .build());
626 } else if (connectPoint.equals(DUAL_LINK_2_CP_3_OUT)) {
627 return ImmutableSet.of(DefaultLink.builder()
628 .providerId(ProviderId.NONE)
629 .type(Link.Type.DIRECT)
630 .src(DUAL_LINK_2_CP_3_OUT)
631 .dst(DUAL_LINK_3_CP_2_IN)
632 .build());
Andrea Campanella490ec3a2018-03-01 16:22:21 +0100633 } else if (connectPoint.equals(DUAL_HOME_CP_1_2)) {
634 return ImmutableSet.of(DefaultLink.builder()
635 .providerId(ProviderId.NONE)
636 .type(Link.Type.DIRECT)
637 .src(DUAL_HOME_CP_1_2)
638 .dst(DUAL_HOME_CP_2_1)
639 .build());
640 } else if (connectPoint.equals(DUAL_HOME_CP_1_3)) {
641 return ImmutableSet.of(DefaultLink.builder()
642 .providerId(ProviderId.NONE)
643 .type(Link.Type.DIRECT)
644 .src(DUAL_HOME_CP_1_3)
645 .dst(DUAL_HOME_CP_3_1)
646 .build());
Andrea Campanella01e886e2017-12-15 15:27:31 +0100647 }
648 return ImmutableSet.of();
649 }
650 }
Andrea Campanella37d10622018-01-18 17:11:42 +0100651
652 private class TestDeviceService extends DeviceServiceAdapter {
653 @Override
654 public Device getDevice(DeviceId deviceId) {
655 if (deviceId.equals(DeviceId.deviceId("nonexistent"))) {
656 return null;
657 }
658 return new DefaultDevice(ProviderId.NONE, DeviceId.deviceId("test"), SWITCH,
659 "test", "test", "test", "test", new ChassisId(),
660 DefaultAnnotations.builder().set("foo", "bar").build());
661 }
662
663 @Override
Andrea Campanella04924b92018-01-17 16:34:51 +0100664 public Port getPort(ConnectPoint cp) {
665 return new DefaultPort(null, cp.port(), true, DefaultAnnotations.builder().build());
666 }
667
668 @Override
Andrea Campanella37d10622018-01-18 17:11:42 +0100669 public boolean isAvailable(DeviceId deviceId) {
Andrea Campanella04924b92018-01-17 16:34:51 +0100670 return !deviceId.equals(OFFLINE_DEVICE);
671 }
672 }
673
674 private class TestEdgePortService extends EdgePortServiceAdapter {
675
676 @Override
677 public boolean isEdgePoint(ConnectPoint point) {
678 return point.equals(MULTICAST_OUT_CP) ||
679 point.equals(MULTICAST_OUT_CP_2);
Andrea Campanella37d10622018-01-18 17:11:42 +0100680 }
681 }
Andrea Campanella7c8e7912018-01-23 12:46:04 +0100682
Andrea Campanellacc2424a2018-03-07 14:27:54 -0800683 private class TestRouteService extends RouteServiceAdapter {
684 @Override
685 public Optional<ResolvedRoute> longestPrefixLookup(IpAddress ip) {
686 return Optional.empty();
687 }
688 }
689
Andrea Campanella7c8e7912018-01-23 12:46:04 +0100690 private class TestMastershipService extends MastershipServiceAdapter {
691 @Override
692 public NodeId getMasterFor(DeviceId deviceId) {
693 return NodeId.nodeId(MASTER_1);
694 }
695 }
Andrea Campanella01e886e2017-12-15 15:27:31 +0100696}