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