blob: f8e4ffd9f2c7131e6e66e2b577a2fdc46cf9d660 [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;
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;
49import org.projectfloodlight.openflow.protocol.OFPortDesc;
50import org.projectfloodlight.openflow.protocol.OFPortReason;
51import org.projectfloodlight.openflow.protocol.OFPortStatus;
52import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
53import org.projectfloodlight.openflow.types.OFPort;
54
alshabibb452fd72015-04-22 20:46:20 -070055import java.util.ArrayList;
56import java.util.Collection;
57import java.util.HashMap;
58import java.util.HashSet;
59import java.util.List;
60import java.util.Map;
61import java.util.Set;
62
63import static org.junit.Assert.*;
64import static org.onosproject.net.Device.Type.SWITCH;
65import static org.onosproject.net.MastershipRole.*;
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070066
67public class OpenFlowDeviceProviderTest {
68
69 private static final ProviderId PID = new ProviderId("of", "test");
70 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
71 private static final Dpid DPID1 = Dpid.dpid(DID1.uri());
72
73 private static final OFPortDesc PD1 = portDesc(1);
74 private static final OFPortDesc PD2 = portDesc(2);
75 private static final OFPortDesc PD3 = portDesc(3);
76
77 private static final List<OFPortDesc> PLIST = Lists.newArrayList(PD1, PD2);
78
79 private static final Device DEV1 =
alshabib7911a052014-10-16 17:49:37 -070080 new DefaultDevice(PID, DID1, SWITCH, "", "", "", "", null);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070081
82 private static final TestOpenFlowSwitch SW1 = new TestOpenFlowSwitch();
83
84 private final OpenFlowDeviceProvider provider = new OpenFlowDeviceProvider();
85 private final TestDeviceRegistry registry = new TestDeviceRegistry();
86 private final TestController controller = new TestController();
87
88 @Before
89 public void startUp() {
90 provider.providerRegistry = registry;
91 provider.controller = controller;
Dusan Pajinbab8a5e2015-07-24 17:37:19 +020092 provider.cfgService = new ComponentConfigAdapter();
Victor Silvaac8dab02016-11-28 16:33:08 -030093 provider.driverService = new DriverServiceAdapter();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070094 controller.switchMap.put(DPID1, SW1);
Dusan Pajinbab8a5e2015-07-24 17:37:19 +020095 provider.activate(null);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070096 assertNotNull("provider should be registered", registry.provider);
97 assertNotNull("listener should be registered", controller.listener);
98 assertEquals("devices not added", 1, registry.connected.size());
99 assertEquals("ports not added", 2, registry.ports.get(DID1).size());
100 }
101
102 @After
103 public void tearDown() {
Dusan Pajinbab8a5e2015-07-24 17:37:19 +0200104 provider.deactivate(null);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700105 assertNull("listener should be removed", controller.listener);
106 provider.controller = null;
107 provider.providerRegistry = null;
108 }
109
110 @Test
111 public void roleChanged() {
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700112 provider.roleChanged(DID1, MASTER);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700113 assertEquals("Should be MASTER", RoleState.MASTER, controller.roleMap.get(DPID1));
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700114 provider.roleChanged(DID1, STANDBY);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700115 assertEquals("Should be EQUAL", RoleState.EQUAL, controller.roleMap.get(DPID1));
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700116 provider.roleChanged(DID1, NONE);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700117 assertEquals("Should be SLAVE", RoleState.SLAVE, controller.roleMap.get(DPID1));
118 }
119
Sithara Punnassery81afbf12016-02-11 17:36:25 -0800120 //sending a features req, msg will be added to sent
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700121 @Test
122 public void triggerProbe() {
Sithara Punnassery81afbf12016-02-11 17:36:25 -0800123 int cur = SW1.sent.size();
124 provider.triggerProbe(DID1);
125 assertEquals("OF message not sent", cur + 1, SW1.sent.size());
126 }
alshabib4785eec2014-12-04 16:45:45 -0800127
Sithara Punnassery81afbf12016-02-11 17:36:25 -0800128 //test receiving features reply
129 @Test
130 public void switchChanged() {
131 controller.listener.switchChanged(DPID1);
132 Collection<PortDescription> updatedDescr = registry.ports.values();
133 for (PortDescription pd : updatedDescr) {
134 assertNotNull("Switch change not handled by the provider service", pd);
135 }
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700136 }
137
138 @Test
139 public void switchRemoved() {
140 controller.listener.switchRemoved(DPID1);
141 assertTrue("device not removed", registry.connected.isEmpty());
142 }
143
144 @Test
145 public void portChanged() {
146 OFPortStatus stat = SW1.factory().buildPortStatus()
147 .setReason(OFPortReason.ADD)
148 .setDesc(PD3)
149 .build();
150 controller.listener.portChanged(DPID1, stat);
Ayaka Koshibe39a04802014-09-22 10:23:54 -0700151 assertNotNull("never went throught the provider service", registry.descr);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700152 assertEquals("port status unhandled", 3, registry.ports.get(DID1).size());
153 }
154
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700155 @Test
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700156 public void receivedRoleReply() {
157 // check translation capabilities
158 controller.listener.receivedRoleReply(DPID1, RoleState.MASTER, RoleState.MASTER);
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700159 assertEquals("wrong role reported", DPID1, registry.roles.get(MASTER));
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700160 controller.listener.receivedRoleReply(DPID1, RoleState.EQUAL, RoleState.MASTER);
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700161 assertEquals("wrong role reported", DPID1, registry.roles.get(STANDBY));
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700162 controller.listener.receivedRoleReply(DPID1, RoleState.SLAVE, RoleState.MASTER);
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700163 assertEquals("wrong role reported", DPID1, registry.roles.get(NONE));
164 }
165
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700166 private static OFPortDesc portDesc(int port) {
167 OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc();
168 builder.setPortNo(OFPort.of(port));
169
170 return builder.build();
171 }
172
173 private class TestDeviceRegistry implements DeviceProviderRegistry {
174 DeviceProvider provider;
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700175
176 Set<DeviceId> connected = new HashSet<>();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700177 Multimap<DeviceId, PortDescription> ports = HashMultimap.create();
Ayaka Koshibe39a04802014-09-22 10:23:54 -0700178 PortDescription descr = null;
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700179 Map<MastershipRole, Dpid> roles = new HashMap<>();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700180
181 @Override
182 public DeviceProviderService register(DeviceProvider provider) {
183 this.provider = provider;
184 return new TestProviderService();
185 }
186
187 @Override
188 public void unregister(DeviceProvider provider) {
189 }
190
191 @Override
192 public Set<ProviderId> getProviders() {
193 return null;
194 }
195
196 private class TestProviderService implements DeviceProviderService {
197
198 @Override
199 public DeviceProvider provider() {
200 return null;
201 }
202
203 @Override
204 public void deviceConnected(DeviceId deviceId,
205 DeviceDescription deviceDescription) {
206 connected.add(deviceId);
207 }
208
209 @Override
210 public void deviceDisconnected(DeviceId deviceId) {
211 connected.remove(deviceId);
212 ports.removeAll(deviceId);
213 }
214
215 @Override
216 public void updatePorts(DeviceId deviceId,
217 List<PortDescription> portDescriptions) {
218 for (PortDescription p : portDescriptions) {
219 ports.put(deviceId, p);
220 }
221 }
222
223 @Override
224 public void portStatusChanged(DeviceId deviceId,
225 PortDescription portDescription) {
Ayaka Koshibe39a04802014-09-22 10:23:54 -0700226 ports.put(deviceId, portDescription);
227 descr = portDescription;
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700228 }
229
tom3f2bbd72014-09-24 12:07:58 -0700230 @Override
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700231 public void receivedRoleReply(DeviceId deviceId,
232 MastershipRole requested, MastershipRole response) {
233 roles.put(requested, Dpid.dpid(deviceId.uri()));
tom3f2bbd72014-09-24 12:07:58 -0700234 }
235
sangho538108b2015-04-08 14:29:20 -0700236 @Override
237 public void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics) {
238
239 }
240
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700241 }
242 }
243
244 private class TestController implements OpenFlowController {
245 OpenFlowSwitchListener listener = null;
246 Map<Dpid, RoleState> roleMap = new HashMap<Dpid, RoleState>();
247 Map<Dpid, OpenFlowSwitch> switchMap = new HashMap<Dpid, OpenFlowSwitch>();
248
249 @Override
250 public Iterable<OpenFlowSwitch> getSwitches() {
251 return switchMap.values();
252 }
253
254 @Override
255 public Iterable<OpenFlowSwitch> getMasterSwitches() {
Thomas Vachuskad07c0922015-10-06 14:48:06 -0700256 return ImmutableSet.of();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700257 }
258
259 @Override
260 public Iterable<OpenFlowSwitch> getEqualSwitches() {
261 return null;
262 }
263
264 @Override
265 public OpenFlowSwitch getSwitch(Dpid dpid) {
266 return switchMap.get(dpid);
267 }
268
269 @Override
270 public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
271 return null;
272 }
273
274 @Override
275 public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
276
277 return null;
278 }
279
280 @Override
281 public void addListener(OpenFlowSwitchListener listener) {
282 this.listener = listener;
283 }
284
285 @Override
286 public void removeListener(OpenFlowSwitchListener listener) {
287 this.listener = null;
288 }
289
290 @Override
Jian Lia78cdb22016-04-21 13:03:58 -0700291 public void addMessageListener(OpenFlowMessageListener listener) {
292
293 }
294
295 @Override
296 public void removeMessageListener(OpenFlowMessageListener listener) {
297
298 }
299
300 @Override
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700301 public void addPacketListener(int priority, PacketListener listener) {
302 }
303
304 @Override
305 public void removePacketListener(PacketListener listener) {
306 }
307
308 @Override
309 public void addEventListener(OpenFlowEventListener listener) {
310 }
311
312 @Override
313 public void removeEventListener(OpenFlowEventListener listener) {
314 }
315
316 @Override
317 public void write(Dpid dpid, OFMessage msg) {
318 }
319
320 @Override
321 public void processPacket(Dpid dpid, OFMessage msg) {
322 }
323
324 @Override
325 public void setRole(Dpid dpid, RoleState role) {
326 roleMap.put(dpid, role);
327 }
328 }
329
330 private static class TestOpenFlowSwitch implements OpenFlowSwitch {
331
332 RoleState state;
333 List<OFMessage> sent = new ArrayList<OFMessage>();
334 OFFactory factory = OFFactoryVer10.INSTANCE;
335
336 @Override
337 public void sendMsg(OFMessage msg) {
338 sent.add(msg);
339 }
340
341 @Override
342 public void sendMsg(List<OFMessage> msgs) {
343 }
344
345 @Override
346 public void handleMessage(OFMessage fromSwitch) {
Sithara Punnassery81afbf12016-02-11 17:36:25 -0800347
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700348 }
349
350 @Override
351 public void setRole(RoleState role) {
352 state = role;
353 }
354
355 @Override
356 public RoleState getRole() {
357 return state;
358 }
359
360 @Override
361 public List<OFPortDesc> getPorts() {
362 return PLIST;
363 }
364
365 @Override
366 public OFFactory factory() {
367 return factory;
368 }
369
370 @Override
371 public String getStringId() {
372 return null;
373 }
374
375 @Override
376 public long getId() {
377 return DPID1.value();
378 }
379
380 @Override
Ray Milkeyd3edd032015-01-16 11:38:58 -0800381 public String manufacturerDescription() {
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700382 return null;
383 }
384
385 @Override
386 public String datapathDescription() {
387 return null;
388 }
389
390 @Override
391 public String hardwareDescription() {
392 return null;
393 }
394
395 @Override
396 public String softwareDescription() {
397 return null;
398 }
399
400 @Override
401 public String serialNumber() {
402 return null;
403 }
404
405 @Override
Yuta HIGUCHI69a27352014-10-31 15:48:37 -0700406 public boolean isConnected() {
407 return true;
408 }
409
410 @Override
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700411 public void disconnectSwitch() {
412 }
413
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700414 @Override
Marc De Leenheerb9311372015-07-09 11:36:49 -0700415 public Device.Type deviceType() {
416 return Device.Type.SWITCH;
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700417 }
418
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700419 @Override
Ray Milkeye53f1712015-01-16 09:17:16 -0800420 public void returnRoleReply(RoleState requested, RoleState response) {
421 }
422
423 @Override
424 public String channelId() {
425 return "1.2.3.4:1";
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700426 }
427
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700428 }
429
430}