blob: 28ab5b2b12ea5e8136f037ea10fe3b27f068b76d [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;
22import org.onlab.packet.EthType;
23import org.onlab.packet.IpAddress;
24import org.onlab.packet.MacAddress;
25import org.onlab.packet.VlanId;
26import org.onosproject.net.ConnectPoint;
27import org.onosproject.net.DefaultLink;
28import org.onosproject.net.DeviceId;
29import org.onosproject.net.Host;
30import org.onosproject.net.Link;
Andrea Campanella01e886e2017-12-15 15:27:31 +010031import org.onosproject.net.driver.DefaultDriver;
32import org.onosproject.net.driver.Driver;
33import org.onosproject.net.driver.DriverServiceAdapter;
34import org.onosproject.net.flow.FlowEntry;
35import org.onosproject.net.flow.FlowRuleServiceAdapter;
36import org.onosproject.net.flow.TrafficSelector;
37import org.onosproject.net.flow.criteria.Criterion;
38import org.onosproject.net.flow.criteria.EthTypeCriterion;
39import org.onosproject.net.flow.criteria.VlanIdCriterion;
40import org.onosproject.net.group.Group;
41import org.onosproject.net.group.GroupServiceAdapter;
42import org.onosproject.net.host.HostServiceAdapter;
43import org.onosproject.net.link.LinkServiceAdapter;
44import org.onosproject.net.provider.ProviderId;
45import org.onosproject.t3.api.StaticPacketTrace;
46import org.slf4j.Logger;
47
48import java.util.HashMap;
49import java.util.Set;
50
51import static org.junit.Assert.assertEquals;
52import static org.junit.Assert.assertNotNull;
53import static org.junit.Assert.assertNull;
54import static org.junit.Assert.assertTrue;
55import static org.onosproject.t3.impl.T3TestObjects.*;
56import static org.slf4j.LoggerFactory.getLogger;
57
58/**
59 * Test Class for Troubleshoot Manager.
60 */
61public class TroubleshootManagerTest {
62
63 private static final Logger log = getLogger(TroubleshootManager.class);
64
65 private TroubleshootManager mngr;
66
67 @Before
68 public void setUp() throws Exception {
69 mngr = new TroubleshootManager();
70 mngr.flowRuleService = new TestFlowRuleService();
71 mngr.hostService = new TestHostService();
72 mngr.linkService = new TestLinkService();
73 mngr.driverService = new TestDriverService();
74 mngr.groupService = new TestGroupService();
75
76 assertNotNull("Manager should not be null", mngr);
77
78 assertNotNull("Flow rule Service should not be null", mngr.flowRuleService);
79 assertNotNull("Host Service should not be null", mngr.hostService);
80 assertNotNull("Group Service should not be null", mngr.groupService);
81 assertNotNull("Driver Service should not be null", mngr.driverService);
82 assertNotNull("Link Service should not be null", mngr.linkService);
83 }
84
85 /**
Andrea Campanella2bc55dd2018-01-18 16:54:34 +010086 * Tests failure on device with no flows.
Andrea Campanella01e886e2017-12-15 15:27:31 +010087 */
88 @Test
89 public void noFlows() {
90 StaticPacketTrace traceFail = mngr.trace(PACKET_OK, ConnectPoint.deviceConnectPoint("test/1"));
91 assertNotNull("Trace should not be null", traceFail);
92 assertNull("Trace should have 0 output", traceFail.getGroupOuputs(SINGLE_FLOW_DEVICE));
93 log.info("trace {}", traceFail.resultMessage());
94 }
95
96 /**
97 * Test a single flow rule that has output port in it.
98 */
99 @Test
100 public void testSingleFlowRule() {
101
102 testSuccess(PACKET_OK, SINGLE_FLOW_IN_CP, SINGLE_FLOW_DEVICE, SINGLE_FLOW_OUT_CP, 1);
103
104 testFaliure(PACKET_FAIL, SINGLE_FLOW_IN_CP, SINGLE_FLOW_DEVICE);
105 }
106
107 /**
108 * Tests two flow rule the last one of which has output port in it.
109 */
110 @Test
111 public void testDualFlowRule() {
112
113 //Test Success
114
Andrea Campanella2bc55dd2018-01-18 16:54:34 +0100115 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, DUAL_FLOW_IN_CP, DUAL_FLOW_DEVICE,
116 DUAL_FLOW_OUT_CP, 1);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100117
118 //Testing Vlan
119 Criterion criterion = traceSuccess.getGroupOuputs(DUAL_FLOW_DEVICE).get(0).
120 getFinalPacket().getCriterion(Criterion.Type.VLAN_VID);
121 assertNotNull("Packet Should have Vlan", criterion);
122
123 VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) criterion;
124
125 assertEquals("Vlan should be 100", VlanId.vlanId((short) 100), vlanIdCriterion.vlanId());
126
127 //Test Faliure
128 testFaliure(PACKET_FAIL, DUAL_FLOW_IN_CP, DUAL_FLOW_DEVICE);
129
130 }
131
132 /**
133 * Test a single flow rule that points to a group with output port in it.
134 */
135 @Test
136 public void flowAndGroup() throws Exception {
137
Andrea Campanella2bc55dd2018-01-18 16:54:34 +0100138 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, GROUP_FLOW_IN_CP, GROUP_FLOW_DEVICE,
139 GROUP_FLOW_OUT_CP, 1);
Andrea Campanella01e886e2017-12-15 15:27:31 +0100140
141 assertTrue("Wrong Output Group", traceSuccess.getGroupOuputs(GROUP_FLOW_DEVICE)
142 .get(0).getGroups().contains(GROUP));
143
144 }
145
146 /**
147 * Test path through a 3 device topology.
148 */
149 @Test
150 public void singlePathTopology() throws Exception {
151
152 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK_TOPO, TOPO_FLOW_1_IN_CP,
153 TOPO_FLOW_3_DEVICE, TOPO_FLOW_3_OUT_CP, 1);
154
155 assertTrue("Incorrect path",
156 traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_2_IN_CP));
157 assertTrue("Incorrect path",
158 traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_2_OUT_CP));
159 assertTrue("Incorrect path",
160 traceSuccess.getCompletePaths().get(0).contains(TOPO_FLOW_3_IN_CP));
161
162 }
163
164 /**
165 * Test path through a 4 device topology with first device that has groups with multiple output buckets.
166 */
167 @Test
168 public void testGroupTopo() throws Exception {
169
170 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK_TOPO, TOPO_FLOW_IN_CP,
171 TOPO_FLOW_3_DEVICE, TOPO_FLOW_3_OUT_CP, 2);
172
173 assertTrue("Incorrect groups",
174 traceSuccess.getGroupOuputs(TOPO_GROUP_FLOW_DEVICE).get(0).getGroups().contains(TOPO_GROUP));
175 assertTrue("Incorrect bucket",
176 traceSuccess.getGroupOuputs(TOPO_GROUP_FLOW_DEVICE).get(1).getGroups().contains(TOPO_GROUP));
177 }
178
179 /**
180 * Test HW support in a single device with 2 flow rules to check hit of static HW rules.
181 */
182 @Test
183 public void hardwareTest() throws Exception {
184
185 StaticPacketTrace traceSuccess = testSuccess(PACKET_OK, HARDWARE_DEVICE_IN_CP,
186 HARDWARE_DEVICE, HARDWARE_DEVICE_OUT_CP, 1);
187
188 assertEquals("wrong ETH type", EthType.EtherType.IPV4.ethType(),
189 ((EthTypeCriterion) traceSuccess.getGroupOuputs(HARDWARE_DEVICE).get(0).getFinalPacket()
190 .getCriterion(Criterion.Type.ETH_TYPE)).ethType());
191
192 }
193
194 private StaticPacketTrace testSuccess(TrafficSelector packet, ConnectPoint in, DeviceId deviceId, ConnectPoint out,
195 int paths) {
196 StaticPacketTrace traceSuccess = mngr.trace(packet, in);
197
198 log.info("trace {}", traceSuccess);
199
200 log.info("trace {}", traceSuccess.resultMessage());
201
202 assertNotNull("trace should not be null", traceSuccess);
203 assertEquals("Trace should have " + paths + " output", paths, traceSuccess.getGroupOuputs(deviceId).size());
204 assertEquals("Trace should only have " + paths + "output", paths, traceSuccess.getCompletePaths().size());
205 assertTrue("Trace should be successful",
206 traceSuccess.resultMessage().contains("Reached required destination Host"));
207 assertEquals("Incorrect Output CP", out,
208 traceSuccess.getGroupOuputs(deviceId).get(0).getOutput());
209
210 return traceSuccess;
211 }
212
213 private void testFaliure(TrafficSelector packet, ConnectPoint in, DeviceId deviceId) {
214 StaticPacketTrace traceFail = mngr.trace(packet, in);
215
216 log.info("trace {}", traceFail.resultMessage());
217
218 assertNotNull("Trace should not be null", traceFail);
219 assertNull("Trace should have 0 output", traceFail.getGroupOuputs(deviceId));
220 }
221
222 private class TestFlowRuleService extends FlowRuleServiceAdapter {
223 @Override
224 public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
225 if (deviceId.equals(SINGLE_FLOW_DEVICE)) {
226 return ImmutableList.of(SINGLE_FLOW_ENTRY);
227 } else if (deviceId.equals(DUAL_FLOW_DEVICE)) {
228 return ImmutableList.of(FIRST_FLOW_ENTRY, SECOND_FLOW_ENTRY);
229 } else if (deviceId.equals(GROUP_FLOW_DEVICE)) {
230 return ImmutableList.of(GROUP_FLOW_ENTRY);
231 } else if (deviceId.equals(TOPO_FLOW_DEVICE) ||
232 deviceId.equals(TOPO_FLOW_2_DEVICE) ||
233 deviceId.equals(TOPO_FLOW_3_DEVICE) ||
234 deviceId.equals(TOPO_FLOW_4_DEVICE)) {
235 return ImmutableList.of(TOPO_SINGLE_FLOW_ENTRY, TOPO_SECOND_INPUT_FLOW_ENTRY);
236 } else if (deviceId.equals(TOPO_GROUP_FLOW_DEVICE)) {
237 return ImmutableList.of(TOPO_GROUP_FLOW_ENTRY);
Andrea Campanella2bc55dd2018-01-18 16:54:34 +0100238 } else if (deviceId.equals(HARDWARE_DEVICE)) {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100239 return ImmutableList.of(HARDWARE_ETH_FLOW_ENTRY, HARDWARE_FLOW_ENTRY);
240 }
241 return ImmutableList.of();
242 }
243 }
244
245 private class TestDriverService extends DriverServiceAdapter {
246 @Override
247 public Driver getDriver(DeviceId deviceId) {
Andrea Campanella2bc55dd2018-01-18 16:54:34 +0100248 if (deviceId.equals(HARDWARE_DEVICE)) {
Andrea Campanella01e886e2017-12-15 15:27:31 +0100249 return new DefaultDriver("ofdpa", ImmutableList.of(),
250 "test", "test", "test", new HashMap<>(), new HashMap<>());
251 }
252 return new DefaultDriver("NotHWDriver", ImmutableList.of(),
253 "test", "test", "test", new HashMap<>(), new HashMap<>());
254 }
255 }
256
257 private class TestGroupService extends GroupServiceAdapter {
258 @Override
259 public Iterable<Group> getGroups(DeviceId deviceId) {
260 if (deviceId.equals(GROUP_FLOW_DEVICE)) {
261 return ImmutableList.of(GROUP);
262 } else if (deviceId.equals(TOPO_GROUP_FLOW_DEVICE)) {
263 return ImmutableList.of(TOPO_GROUP);
264 }
265 return ImmutableList.of();
266 }
267 }
268
269 private class TestHostService extends HostServiceAdapter {
270 @Override
271 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
272 if (connectPoint.equals(TOPO_FLOW_3_OUT_CP)) {
273 return ImmutableSet.of(H2);
274 }
275 return ImmutableSet.of(H1);
276 }
277
278 @Override
279 public Set<Host> getHostsByMac(MacAddress mac) {
280 if (mac.equals(H1.mac())) {
281 return ImmutableSet.of(H1);
282 } else if (mac.equals(H2.mac())) {
283 return ImmutableSet.of(H2);
284 }
285 return ImmutableSet.of();
286 }
287
288 @Override
289 public Set<Host> getHostsByIp(IpAddress ip) {
290 if ((H1.ipAddresses().contains(ip))) {
291 return ImmutableSet.of(H1);
292 } else if ((H2.ipAddresses().contains(ip))) {
293 return ImmutableSet.of(H2);
294 }
295 return ImmutableSet.of();
296 }
297 }
298
299 private class TestLinkService extends LinkServiceAdapter {
300 @Override
301 public Set<Link> getEgressLinks(ConnectPoint connectPoint) {
302 if (connectPoint.equals(TOPO_FLOW_1_OUT_CP)
303 || connectPoint.equals(TOPO_FLOW_OUT_CP_1)) {
304 return ImmutableSet.of(DefaultLink.builder()
305 .providerId(ProviderId.NONE)
306 .type(Link.Type.DIRECT)
307 .src(connectPoint)
308 .dst(TOPO_FLOW_2_IN_CP)
309 .build());
310 } else if (connectPoint.equals(TOPO_FLOW_2_OUT_CP)) {
311 return ImmutableSet.of(DefaultLink.builder()
312 .providerId(ProviderId.NONE)
313 .type(Link.Type.DIRECT)
314 .src(TOPO_FLOW_2_OUT_CP)
315 .dst(TOPO_FLOW_3_IN_CP)
316 .build());
317 } else if (connectPoint.equals(TOPO_FLOW_OUT_CP_2)) {
318 return ImmutableSet.of(DefaultLink.builder()
319 .providerId(ProviderId.NONE)
320 .type(Link.Type.DIRECT)
321 .src(TOPO_FLOW_OUT_CP_2)
322 .dst(TOPO_FLOW_4_IN_CP)
323 .build());
324 } else if (connectPoint.equals(TOPO_FLOW_4_OUT_CP)) {
325 return ImmutableSet.of(DefaultLink.builder()
326 .providerId(ProviderId.NONE)
327 .type(Link.Type.DIRECT)
328 .src(TOPO_FLOW_4_OUT_CP)
329 .dst(TOPO_FLOW_3_IN_2_CP)
330 .build());
331 }
332 return ImmutableSet.of();
333 }
334 }
335}