blob: 8167b04c74e5e3ceaab011cd839d2d01ca766cbc [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2014-present Open Networking Foundation
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.provider.of.device.impl;
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070017
alshabibb452fd72015-04-22 20:46:20 -070018import com.google.common.collect.HashMultimap;
Thomas Vachuskad07c0922015-10-06 14:48:06 -070019import com.google.common.collect.ImmutableSet;
alshabibb452fd72015-04-22 20:46:20 -070020import com.google.common.collect.Lists;
21import com.google.common.collect.Multimap;
Dusan Pajinbab8a5e2015-07-24 17:37:19 +020022
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070023import org.junit.After;
24import org.junit.Before;
25import org.junit.Test;
Dusan Pajinbab8a5e2015-07-24 17:37:19 +020026import org.onosproject.cfg.ComponentConfigAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080027import org.onosproject.net.DefaultDevice;
28import org.onosproject.net.Device;
29import org.onosproject.net.DeviceId;
30import org.onosproject.net.MastershipRole;
31import org.onosproject.net.device.DeviceDescription;
32import org.onosproject.net.device.DeviceProvider;
33import org.onosproject.net.device.DeviceProviderRegistry;
34import org.onosproject.net.device.DeviceProviderService;
35import org.onosproject.net.device.PortDescription;
sangho538108b2015-04-08 14:29:20 -070036import org.onosproject.net.device.PortStatistics;
Victor Silvaac8dab02016-11-28 16:33:08 -030037import org.onosproject.net.driver.DriverServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080038import org.onosproject.net.provider.ProviderId;
39import org.onosproject.openflow.controller.Dpid;
40import org.onosproject.openflow.controller.OpenFlowController;
41import org.onosproject.openflow.controller.OpenFlowEventListener;
Jian Lia78cdb22016-04-21 13:03:58 -070042import org.onosproject.openflow.controller.OpenFlowMessageListener;
Brian O'Connorabafb502014-12-02 22:26:20 -080043import org.onosproject.openflow.controller.OpenFlowSwitch;
44import org.onosproject.openflow.controller.OpenFlowSwitchListener;
45import org.onosproject.openflow.controller.PacketListener;
46import org.onosproject.openflow.controller.RoleState;
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070047import org.projectfloodlight.openflow.protocol.OFFactory;
48import org.projectfloodlight.openflow.protocol.OFMessage;
Jordi Ortizaa8de492016-12-01 00:21:36 +010049import org.projectfloodlight.openflow.protocol.OFMeterFeatures;
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070050import org.projectfloodlight.openflow.protocol.OFPortDesc;
51import org.projectfloodlight.openflow.protocol.OFPortReason;
52import org.projectfloodlight.openflow.protocol.OFPortStatus;
53import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
54import org.projectfloodlight.openflow.types.OFPort;
55
alshabibb452fd72015-04-22 20:46:20 -070056import java.util.ArrayList;
57import java.util.Collection;
58import java.util.HashMap;
59import java.util.HashSet;
60import java.util.List;
61import java.util.Map;
62import java.util.Set;
Marc De Leenheer8aba62f2017-04-25 14:33:37 -070063import java.util.concurrent.CompletableFuture;
alshabibb452fd72015-04-22 20:46:20 -070064
65import static org.junit.Assert.*;
66import static org.onosproject.net.Device.Type.SWITCH;
67import static org.onosproject.net.MastershipRole.*;
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070068
69public class OpenFlowDeviceProviderTest {
70
71 private static final ProviderId PID = new ProviderId("of", "test");
72 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
73 private static final Dpid DPID1 = Dpid.dpid(DID1.uri());
74
75 private static final OFPortDesc PD1 = portDesc(1);
76 private static final OFPortDesc PD2 = portDesc(2);
77 private static final OFPortDesc PD3 = portDesc(3);
78
79 private static final List<OFPortDesc> PLIST = Lists.newArrayList(PD1, PD2);
80
81 private static final Device DEV1 =
alshabib7911a052014-10-16 17:49:37 -070082 new DefaultDevice(PID, DID1, SWITCH, "", "", "", "", null);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070083
84 private static final TestOpenFlowSwitch SW1 = new TestOpenFlowSwitch();
85
86 private final OpenFlowDeviceProvider provider = new OpenFlowDeviceProvider();
87 private final TestDeviceRegistry registry = new TestDeviceRegistry();
88 private final TestController controller = new TestController();
89
90 @Before
91 public void startUp() {
92 provider.providerRegistry = registry;
93 provider.controller = controller;
Dusan Pajinbab8a5e2015-07-24 17:37:19 +020094 provider.cfgService = new ComponentConfigAdapter();
Victor Silvaac8dab02016-11-28 16:33:08 -030095 provider.driverService = new DriverServiceAdapter();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070096 controller.switchMap.put(DPID1, SW1);
Dusan Pajinbab8a5e2015-07-24 17:37:19 +020097 provider.activate(null);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070098 assertNotNull("provider should be registered", registry.provider);
99 assertNotNull("listener should be registered", controller.listener);
100 assertEquals("devices not added", 1, registry.connected.size());
101 assertEquals("ports not added", 2, registry.ports.get(DID1).size());
102 }
103
104 @After
105 public void tearDown() {
Dusan Pajinbab8a5e2015-07-24 17:37:19 +0200106 provider.deactivate(null);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700107 assertNull("listener should be removed", controller.listener);
108 provider.controller = null;
109 provider.providerRegistry = null;
110 }
111
112 @Test
113 public void roleChanged() {
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700114 provider.roleChanged(DID1, MASTER);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700115 assertEquals("Should be MASTER", RoleState.MASTER, controller.roleMap.get(DPID1));
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700116 provider.roleChanged(DID1, STANDBY);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700117 assertEquals("Should be EQUAL", RoleState.EQUAL, controller.roleMap.get(DPID1));
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700118 provider.roleChanged(DID1, NONE);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700119 assertEquals("Should be SLAVE", RoleState.SLAVE, controller.roleMap.get(DPID1));
120 }
121
Sithara Punnassery81afbf12016-02-11 17:36:25 -0800122 //sending a features req, msg will be added to sent
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700123 @Test
124 public void triggerProbe() {
Sithara Punnassery81afbf12016-02-11 17:36:25 -0800125 int cur = SW1.sent.size();
126 provider.triggerProbe(DID1);
127 assertEquals("OF message not sent", cur + 1, SW1.sent.size());
128 }
alshabib4785eec2014-12-04 16:45:45 -0800129
Sithara Punnassery81afbf12016-02-11 17:36:25 -0800130 //test receiving features reply
131 @Test
132 public void switchChanged() {
133 controller.listener.switchChanged(DPID1);
134 Collection<PortDescription> updatedDescr = registry.ports.values();
135 for (PortDescription pd : updatedDescr) {
136 assertNotNull("Switch change not handled by the provider service", pd);
137 }
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700138 }
139
140 @Test
141 public void switchRemoved() {
142 controller.listener.switchRemoved(DPID1);
143 assertTrue("device not removed", registry.connected.isEmpty());
144 }
145
146 @Test
147 public void portChanged() {
148 OFPortStatus stat = SW1.factory().buildPortStatus()
149 .setReason(OFPortReason.ADD)
150 .setDesc(PD3)
151 .build();
152 controller.listener.portChanged(DPID1, stat);
Ayaka Koshibe39a04802014-09-22 10:23:54 -0700153 assertNotNull("never went throught the provider service", registry.descr);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700154 assertEquals("port status unhandled", 3, registry.ports.get(DID1).size());
155 }
156
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700157 @Test
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700158 public void receivedRoleReply() {
159 // check translation capabilities
160 controller.listener.receivedRoleReply(DPID1, RoleState.MASTER, RoleState.MASTER);
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700161 assertEquals("wrong role reported", DPID1, registry.roles.get(MASTER));
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700162 controller.listener.receivedRoleReply(DPID1, RoleState.EQUAL, RoleState.MASTER);
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700163 assertEquals("wrong role reported", DPID1, registry.roles.get(STANDBY));
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700164 controller.listener.receivedRoleReply(DPID1, RoleState.SLAVE, RoleState.MASTER);
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700165 assertEquals("wrong role reported", DPID1, registry.roles.get(NONE));
166 }
167
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700168 private static OFPortDesc portDesc(int port) {
169 OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc();
170 builder.setPortNo(OFPort.of(port));
171
172 return builder.build();
173 }
174
175 private class TestDeviceRegistry implements DeviceProviderRegistry {
176 DeviceProvider provider;
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700177
178 Set<DeviceId> connected = new HashSet<>();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700179 Multimap<DeviceId, PortDescription> ports = HashMultimap.create();
Ayaka Koshibe39a04802014-09-22 10:23:54 -0700180 PortDescription descr = null;
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700181 Map<MastershipRole, Dpid> roles = new HashMap<>();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700182
183 @Override
184 public DeviceProviderService register(DeviceProvider provider) {
185 this.provider = provider;
186 return new TestProviderService();
187 }
188
189 @Override
190 public void unregister(DeviceProvider provider) {
191 }
192
193 @Override
194 public Set<ProviderId> getProviders() {
195 return null;
196 }
197
198 private class TestProviderService implements DeviceProviderService {
199
200 @Override
201 public DeviceProvider provider() {
202 return null;
203 }
204
205 @Override
206 public void deviceConnected(DeviceId deviceId,
207 DeviceDescription deviceDescription) {
208 connected.add(deviceId);
209 }
210
211 @Override
212 public void deviceDisconnected(DeviceId deviceId) {
213 connected.remove(deviceId);
214 ports.removeAll(deviceId);
215 }
216
217 @Override
218 public void updatePorts(DeviceId deviceId,
219 List<PortDescription> portDescriptions) {
220 for (PortDescription p : portDescriptions) {
221 ports.put(deviceId, p);
222 }
223 }
224
225 @Override
226 public void portStatusChanged(DeviceId deviceId,
227 PortDescription portDescription) {
Ayaka Koshibe39a04802014-09-22 10:23:54 -0700228 ports.put(deviceId, portDescription);
229 descr = portDescription;
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700230 }
231
tom3f2bbd72014-09-24 12:07:58 -0700232 @Override
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700233 public void receivedRoleReply(DeviceId deviceId,
234 MastershipRole requested, MastershipRole response) {
235 roles.put(requested, Dpid.dpid(deviceId.uri()));
tom3f2bbd72014-09-24 12:07:58 -0700236 }
237
sangho538108b2015-04-08 14:29:20 -0700238 @Override
239 public void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics) {
240
241 }
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700242 }
243 }
244
245 private class TestController implements OpenFlowController {
246 OpenFlowSwitchListener listener = null;
247 Map<Dpid, RoleState> roleMap = new HashMap<Dpid, RoleState>();
248 Map<Dpid, OpenFlowSwitch> switchMap = new HashMap<Dpid, OpenFlowSwitch>();
249
250 @Override
251 public Iterable<OpenFlowSwitch> getSwitches() {
252 return switchMap.values();
253 }
254
255 @Override
256 public Iterable<OpenFlowSwitch> getMasterSwitches() {
Thomas Vachuskad07c0922015-10-06 14:48:06 -0700257 return ImmutableSet.of();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700258 }
259
260 @Override
261 public Iterable<OpenFlowSwitch> getEqualSwitches() {
262 return null;
263 }
264
265 @Override
266 public OpenFlowSwitch getSwitch(Dpid dpid) {
267 return switchMap.get(dpid);
268 }
269
270 @Override
271 public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
272 return null;
273 }
274
275 @Override
276 public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
277
278 return null;
279 }
280
281 @Override
282 public void addListener(OpenFlowSwitchListener listener) {
283 this.listener = listener;
284 }
285
286 @Override
287 public void removeListener(OpenFlowSwitchListener listener) {
288 this.listener = null;
289 }
290
291 @Override
Jian Lia78cdb22016-04-21 13:03:58 -0700292 public void addMessageListener(OpenFlowMessageListener listener) {
293
294 }
295
296 @Override
297 public void removeMessageListener(OpenFlowMessageListener listener) {
298
299 }
300
301 @Override
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700302 public void addPacketListener(int priority, PacketListener listener) {
303 }
304
305 @Override
306 public void removePacketListener(PacketListener listener) {
307 }
308
309 @Override
310 public void addEventListener(OpenFlowEventListener listener) {
311 }
312
313 @Override
314 public void removeEventListener(OpenFlowEventListener listener) {
315 }
316
317 @Override
318 public void write(Dpid dpid, OFMessage msg) {
319 }
320
321 @Override
Marc De Leenheer8aba62f2017-04-25 14:33:37 -0700322 public CompletableFuture<OFMessage> writeResponse(Dpid dpid, OFMessage msg) {
323 return null;
324 }
325
326 @Override
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700327 public void processPacket(Dpid dpid, OFMessage msg) {
328 }
329
330 @Override
331 public void setRole(Dpid dpid, RoleState role) {
332 roleMap.put(dpid, role);
333 }
334 }
335
336 private static class TestOpenFlowSwitch implements OpenFlowSwitch {
337
338 RoleState state;
339 List<OFMessage> sent = new ArrayList<OFMessage>();
340 OFFactory factory = OFFactoryVer10.INSTANCE;
341
342 @Override
343 public void sendMsg(OFMessage msg) {
344 sent.add(msg);
345 }
346
347 @Override
348 public void sendMsg(List<OFMessage> msgs) {
349 }
350
351 @Override
352 public void handleMessage(OFMessage fromSwitch) {
Sithara Punnassery81afbf12016-02-11 17:36:25 -0800353
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700354 }
355
356 @Override
357 public void setRole(RoleState role) {
358 state = role;
359 }
360
361 @Override
362 public RoleState getRole() {
363 return state;
364 }
365
366 @Override
367 public List<OFPortDesc> getPorts() {
368 return PLIST;
369 }
370
371 @Override
Jordi Ortizaa8de492016-12-01 00:21:36 +0100372 public OFMeterFeatures getMeterFeatures() {
373 return null;
374 }
375
376 @Override
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700377 public OFFactory factory() {
378 return factory;
379 }
380
381 @Override
382 public String getStringId() {
383 return null;
384 }
385
386 @Override
387 public long getId() {
388 return DPID1.value();
389 }
390
391 @Override
Ray Milkeyd3edd032015-01-16 11:38:58 -0800392 public String manufacturerDescription() {
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700393 return null;
394 }
395
396 @Override
397 public String datapathDescription() {
398 return null;
399 }
400
401 @Override
402 public String hardwareDescription() {
403 return null;
404 }
405
406 @Override
407 public String softwareDescription() {
408 return null;
409 }
410
411 @Override
412 public String serialNumber() {
413 return null;
414 }
415
416 @Override
Yuta HIGUCHI69a27352014-10-31 15:48:37 -0700417 public boolean isConnected() {
418 return true;
419 }
420
421 @Override
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700422 public void disconnectSwitch() {
423 }
424
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700425 @Override
Marc De Leenheerb9311372015-07-09 11:36:49 -0700426 public Device.Type deviceType() {
427 return Device.Type.SWITCH;
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700428 }
429
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700430 @Override
Ray Milkeye53f1712015-01-16 09:17:16 -0800431 public void returnRoleReply(RoleState requested, RoleState response) {
432 }
433
434 @Override
435 public String channelId() {
436 return "1.2.3.4:1";
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700437 }
438
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700439 }
440
441}