blob: 02465f1a9bdb2e8410f85a667ce5b3796de0a09d [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
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;
Brian O'Connorabafb502014-12-02 22:26:20 -080037import org.onosproject.net.provider.ProviderId;
38import org.onosproject.openflow.controller.Dpid;
39import org.onosproject.openflow.controller.OpenFlowController;
40import org.onosproject.openflow.controller.OpenFlowEventListener;
41import org.onosproject.openflow.controller.OpenFlowSwitch;
42import org.onosproject.openflow.controller.OpenFlowSwitchListener;
43import org.onosproject.openflow.controller.PacketListener;
44import org.onosproject.openflow.controller.RoleState;
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070045import org.projectfloodlight.openflow.protocol.OFFactory;
46import org.projectfloodlight.openflow.protocol.OFMessage;
47import org.projectfloodlight.openflow.protocol.OFPortDesc;
48import org.projectfloodlight.openflow.protocol.OFPortReason;
49import org.projectfloodlight.openflow.protocol.OFPortStatus;
50import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
51import org.projectfloodlight.openflow.types.OFPort;
52
alshabibb452fd72015-04-22 20:46:20 -070053import java.util.ArrayList;
54import java.util.Collection;
55import java.util.HashMap;
56import java.util.HashSet;
57import java.util.List;
58import java.util.Map;
59import java.util.Set;
60
61import static org.junit.Assert.*;
62import static org.onosproject.net.Device.Type.SWITCH;
63import static org.onosproject.net.MastershipRole.*;
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070064
65public class OpenFlowDeviceProviderTest {
66
67 private static final ProviderId PID = new ProviderId("of", "test");
68 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
69 private static final Dpid DPID1 = Dpid.dpid(DID1.uri());
70
71 private static final OFPortDesc PD1 = portDesc(1);
72 private static final OFPortDesc PD2 = portDesc(2);
73 private static final OFPortDesc PD3 = portDesc(3);
74
75 private static final List<OFPortDesc> PLIST = Lists.newArrayList(PD1, PD2);
76
77 private static final Device DEV1 =
alshabib7911a052014-10-16 17:49:37 -070078 new DefaultDevice(PID, DID1, SWITCH, "", "", "", "", null);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070079
80 private static final TestOpenFlowSwitch SW1 = new TestOpenFlowSwitch();
81
82 private final OpenFlowDeviceProvider provider = new OpenFlowDeviceProvider();
83 private final TestDeviceRegistry registry = new TestDeviceRegistry();
84 private final TestController controller = new TestController();
85
86 @Before
87 public void startUp() {
88 provider.providerRegistry = registry;
89 provider.controller = controller;
Dusan Pajinbab8a5e2015-07-24 17:37:19 +020090 provider.cfgService = new ComponentConfigAdapter();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070091 controller.switchMap.put(DPID1, SW1);
Dusan Pajinbab8a5e2015-07-24 17:37:19 +020092 provider.activate(null);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070093 assertNotNull("provider should be registered", registry.provider);
94 assertNotNull("listener should be registered", controller.listener);
95 assertEquals("devices not added", 1, registry.connected.size());
96 assertEquals("ports not added", 2, registry.ports.get(DID1).size());
97 }
98
99 @After
100 public void tearDown() {
Dusan Pajinbab8a5e2015-07-24 17:37:19 +0200101 provider.deactivate(null);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700102 assertNull("listener should be removed", controller.listener);
103 provider.controller = null;
104 provider.providerRegistry = null;
105 }
106
107 @Test
108 public void roleChanged() {
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700109 provider.roleChanged(DID1, MASTER);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700110 assertEquals("Should be MASTER", RoleState.MASTER, controller.roleMap.get(DPID1));
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700111 provider.roleChanged(DID1, STANDBY);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700112 assertEquals("Should be EQUAL", RoleState.EQUAL, controller.roleMap.get(DPID1));
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700113 provider.roleChanged(DID1, NONE);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700114 assertEquals("Should be SLAVE", RoleState.SLAVE, controller.roleMap.get(DPID1));
115 }
116
Sithara Punnassery81afbf12016-02-11 17:36:25 -0800117 //sending a features req, msg will be added to sent
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700118 @Test
119 public void triggerProbe() {
Sithara Punnassery81afbf12016-02-11 17:36:25 -0800120 int cur = SW1.sent.size();
121 provider.triggerProbe(DID1);
122 assertEquals("OF message not sent", cur + 1, SW1.sent.size());
123 }
alshabib4785eec2014-12-04 16:45:45 -0800124
Sithara Punnassery81afbf12016-02-11 17:36:25 -0800125 //test receiving features reply
126 @Test
127 public void switchChanged() {
128 controller.listener.switchChanged(DPID1);
129 Collection<PortDescription> updatedDescr = registry.ports.values();
130 for (PortDescription pd : updatedDescr) {
131 assertNotNull("Switch change not handled by the provider service", pd);
132 }
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700133 }
134
135 @Test
136 public void switchRemoved() {
137 controller.listener.switchRemoved(DPID1);
138 assertTrue("device not removed", registry.connected.isEmpty());
139 }
140
141 @Test
142 public void portChanged() {
143 OFPortStatus stat = SW1.factory().buildPortStatus()
144 .setReason(OFPortReason.ADD)
145 .setDesc(PD3)
146 .build();
147 controller.listener.portChanged(DPID1, stat);
Ayaka Koshibe39a04802014-09-22 10:23:54 -0700148 assertNotNull("never went throught the provider service", registry.descr);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700149 assertEquals("port status unhandled", 3, registry.ports.get(DID1).size());
150 }
151
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700152 @Test
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700153 public void receivedRoleReply() {
154 // check translation capabilities
155 controller.listener.receivedRoleReply(DPID1, RoleState.MASTER, RoleState.MASTER);
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700156 assertEquals("wrong role reported", DPID1, registry.roles.get(MASTER));
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700157 controller.listener.receivedRoleReply(DPID1, RoleState.EQUAL, RoleState.MASTER);
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700158 assertEquals("wrong role reported", DPID1, registry.roles.get(STANDBY));
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700159 controller.listener.receivedRoleReply(DPID1, RoleState.SLAVE, RoleState.MASTER);
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700160 assertEquals("wrong role reported", DPID1, registry.roles.get(NONE));
161 }
162
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700163 private static OFPortDesc portDesc(int port) {
164 OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc();
165 builder.setPortNo(OFPort.of(port));
166
167 return builder.build();
168 }
169
170 private class TestDeviceRegistry implements DeviceProviderRegistry {
171 DeviceProvider provider;
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700172
173 Set<DeviceId> connected = new HashSet<>();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700174 Multimap<DeviceId, PortDescription> ports = HashMultimap.create();
Ayaka Koshibe39a04802014-09-22 10:23:54 -0700175 PortDescription descr = null;
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700176 Map<MastershipRole, Dpid> roles = new HashMap<>();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700177
178 @Override
179 public DeviceProviderService register(DeviceProvider provider) {
180 this.provider = provider;
181 return new TestProviderService();
182 }
183
184 @Override
185 public void unregister(DeviceProvider provider) {
186 }
187
188 @Override
189 public Set<ProviderId> getProviders() {
190 return null;
191 }
192
193 private class TestProviderService implements DeviceProviderService {
194
195 @Override
196 public DeviceProvider provider() {
197 return null;
198 }
199
200 @Override
201 public void deviceConnected(DeviceId deviceId,
202 DeviceDescription deviceDescription) {
203 connected.add(deviceId);
204 }
205
206 @Override
207 public void deviceDisconnected(DeviceId deviceId) {
208 connected.remove(deviceId);
209 ports.removeAll(deviceId);
210 }
211
212 @Override
213 public void updatePorts(DeviceId deviceId,
214 List<PortDescription> portDescriptions) {
215 for (PortDescription p : portDescriptions) {
216 ports.put(deviceId, p);
217 }
218 }
219
220 @Override
221 public void portStatusChanged(DeviceId deviceId,
222 PortDescription portDescription) {
Ayaka Koshibe39a04802014-09-22 10:23:54 -0700223 ports.put(deviceId, portDescription);
224 descr = portDescription;
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700225 }
226
tom3f2bbd72014-09-24 12:07:58 -0700227 @Override
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700228 public void receivedRoleReply(DeviceId deviceId,
229 MastershipRole requested, MastershipRole response) {
230 roles.put(requested, Dpid.dpid(deviceId.uri()));
tom3f2bbd72014-09-24 12:07:58 -0700231 }
232
sangho538108b2015-04-08 14:29:20 -0700233 @Override
234 public void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics) {
235
236 }
237
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700238 }
239 }
240
241 private class TestController implements OpenFlowController {
242 OpenFlowSwitchListener listener = null;
243 Map<Dpid, RoleState> roleMap = new HashMap<Dpid, RoleState>();
244 Map<Dpid, OpenFlowSwitch> switchMap = new HashMap<Dpid, OpenFlowSwitch>();
245
246 @Override
247 public Iterable<OpenFlowSwitch> getSwitches() {
248 return switchMap.values();
249 }
250
251 @Override
252 public Iterable<OpenFlowSwitch> getMasterSwitches() {
Thomas Vachuskad07c0922015-10-06 14:48:06 -0700253 return ImmutableSet.of();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700254 }
255
256 @Override
257 public Iterable<OpenFlowSwitch> getEqualSwitches() {
258 return null;
259 }
260
261 @Override
262 public OpenFlowSwitch getSwitch(Dpid dpid) {
263 return switchMap.get(dpid);
264 }
265
266 @Override
267 public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
268 return null;
269 }
270
271 @Override
272 public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
273
274 return null;
275 }
276
277 @Override
Jian Li28247b52016-01-07 17:24:15 -0800278 public void monitorAllEvents(boolean monitor) {
279 }
280
281 @Override
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700282 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
292 public void addPacketListener(int priority, PacketListener listener) {
293 }
294
295 @Override
296 public void removePacketListener(PacketListener listener) {
297 }
298
299 @Override
300 public void addEventListener(OpenFlowEventListener listener) {
301 }
302
303 @Override
304 public void removeEventListener(OpenFlowEventListener listener) {
305 }
306
307 @Override
308 public void write(Dpid dpid, OFMessage msg) {
309 }
310
311 @Override
312 public void processPacket(Dpid dpid, OFMessage msg) {
313 }
314
315 @Override
316 public void setRole(Dpid dpid, RoleState role) {
317 roleMap.put(dpid, role);
318 }
319 }
320
321 private static class TestOpenFlowSwitch implements OpenFlowSwitch {
322
323 RoleState state;
324 List<OFMessage> sent = new ArrayList<OFMessage>();
325 OFFactory factory = OFFactoryVer10.INSTANCE;
326
327 @Override
328 public void sendMsg(OFMessage msg) {
329 sent.add(msg);
330 }
331
332 @Override
333 public void sendMsg(List<OFMessage> msgs) {
334 }
335
336 @Override
337 public void handleMessage(OFMessage fromSwitch) {
Sithara Punnassery81afbf12016-02-11 17:36:25 -0800338
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700339 }
340
341 @Override
342 public void setRole(RoleState role) {
343 state = role;
344 }
345
346 @Override
347 public RoleState getRole() {
348 return state;
349 }
350
351 @Override
352 public List<OFPortDesc> getPorts() {
353 return PLIST;
354 }
355
356 @Override
357 public OFFactory factory() {
358 return factory;
359 }
360
361 @Override
362 public String getStringId() {
363 return null;
364 }
365
366 @Override
367 public long getId() {
368 return DPID1.value();
369 }
370
371 @Override
Ray Milkeyd3edd032015-01-16 11:38:58 -0800372 public String manufacturerDescription() {
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700373 return null;
374 }
375
376 @Override
377 public String datapathDescription() {
378 return null;
379 }
380
381 @Override
382 public String hardwareDescription() {
383 return null;
384 }
385
386 @Override
387 public String softwareDescription() {
388 return null;
389 }
390
391 @Override
392 public String serialNumber() {
393 return null;
394 }
395
396 @Override
Yuta HIGUCHI69a27352014-10-31 15:48:37 -0700397 public boolean isConnected() {
398 return true;
399 }
400
401 @Override
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700402 public void disconnectSwitch() {
403 }
404
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700405 @Override
Marc De Leenheerb9311372015-07-09 11:36:49 -0700406 public Device.Type deviceType() {
407 return Device.Type.SWITCH;
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700408 }
409
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700410 @Override
Ray Milkeye53f1712015-01-16 09:17:16 -0800411 public void returnRoleReply(RoleState requested, RoleState response) {
412 }
413
414 @Override
415 public String channelId() {
416 return "1.2.3.4:1";
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700417 }
418
Jian Li152b8852015-12-07 14:47:25 -0800419 @Override
420 public void addEventListener(OpenFlowEventListener listener) {
421 }
422
423 @Override
424 public void removeEventListener(OpenFlowEventListener listener) {
425 }
426
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700427 }
428
429}