blob: 88c68a990edf2ac1a383250fec73772596c34647 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 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 */
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070016package org.onlab.onos.provider.of.device.impl;
17
18import static org.junit.Assert.assertEquals;
19import static org.junit.Assert.assertNotNull;
20import static org.junit.Assert.assertNull;
21import static org.junit.Assert.assertTrue;
22import static org.onlab.onos.net.Device.Type.*;
23import static org.onlab.onos.net.MastershipRole.*;
24
25import java.util.ArrayList;
26import java.util.HashMap;
27import java.util.HashSet;
28import java.util.List;
29import java.util.Map;
30import java.util.Set;
31
32import org.junit.After;
33import org.junit.Before;
34import org.junit.Test;
35import org.onlab.onos.net.DefaultDevice;
36import org.onlab.onos.net.Device;
37import org.onlab.onos.net.DeviceId;
tom3f2bbd72014-09-24 12:07:58 -070038import org.onlab.onos.net.MastershipRole;
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070039import org.onlab.onos.net.device.DeviceDescription;
40import org.onlab.onos.net.device.DeviceProvider;
41import org.onlab.onos.net.device.DeviceProviderRegistry;
42import org.onlab.onos.net.device.DeviceProviderService;
43import org.onlab.onos.net.device.PortDescription;
44import org.onlab.onos.net.provider.ProviderId;
45import org.onlab.onos.openflow.controller.Dpid;
46import org.onlab.onos.openflow.controller.OpenFlowController;
47import org.onlab.onos.openflow.controller.OpenFlowEventListener;
48import org.onlab.onos.openflow.controller.OpenFlowSwitch;
49import org.onlab.onos.openflow.controller.OpenFlowSwitchListener;
50import org.onlab.onos.openflow.controller.PacketListener;
51import org.onlab.onos.openflow.controller.RoleState;
52import org.projectfloodlight.openflow.protocol.OFFactory;
53import org.projectfloodlight.openflow.protocol.OFMessage;
54import org.projectfloodlight.openflow.protocol.OFPortDesc;
55import org.projectfloodlight.openflow.protocol.OFPortReason;
56import org.projectfloodlight.openflow.protocol.OFPortStatus;
57import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
58import org.projectfloodlight.openflow.types.OFPort;
59
60import com.google.common.collect.HashMultimap;
61import com.google.common.collect.Lists;
62import com.google.common.collect.Multimap;
63
64public class OpenFlowDeviceProviderTest {
65
66 private static final ProviderId PID = new ProviderId("of", "test");
67 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
68 private static final Dpid DPID1 = Dpid.dpid(DID1.uri());
69
70 private static final OFPortDesc PD1 = portDesc(1);
71 private static final OFPortDesc PD2 = portDesc(2);
72 private static final OFPortDesc PD3 = portDesc(3);
73
74 private static final List<OFPortDesc> PLIST = Lists.newArrayList(PD1, PD2);
75
76 private static final Device DEV1 =
alshabib7911a052014-10-16 17:49:37 -070077 new DefaultDevice(PID, DID1, SWITCH, "", "", "", "", null);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070078
79 private static final TestOpenFlowSwitch SW1 = new TestOpenFlowSwitch();
80
81 private final OpenFlowDeviceProvider provider = new OpenFlowDeviceProvider();
82 private final TestDeviceRegistry registry = new TestDeviceRegistry();
83 private final TestController controller = new TestController();
84
85 @Before
86 public void startUp() {
87 provider.providerRegistry = registry;
88 provider.controller = controller;
89 controller.switchMap.put(DPID1, SW1);
90 provider.activate();
91 assertNotNull("provider should be registered", registry.provider);
92 assertNotNull("listener should be registered", controller.listener);
93 assertEquals("devices not added", 1, registry.connected.size());
94 assertEquals("ports not added", 2, registry.ports.get(DID1).size());
95 }
96
97 @After
98 public void tearDown() {
99 provider.deactivate();
100 assertTrue("devices should be removed", registry.connected.isEmpty());
101 assertNull("listener should be removed", controller.listener);
102 provider.controller = null;
103 provider.providerRegistry = null;
104 }
105
106 @Test
107 public void roleChanged() {
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700108 provider.roleChanged(DID1, MASTER);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700109 assertEquals("Should be MASTER", RoleState.MASTER, controller.roleMap.get(DPID1));
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700110 provider.roleChanged(DID1, STANDBY);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700111 assertEquals("Should be EQUAL", RoleState.EQUAL, controller.roleMap.get(DPID1));
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700112 provider.roleChanged(DID1, NONE);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700113 assertEquals("Should be SLAVE", RoleState.SLAVE, controller.roleMap.get(DPID1));
114 }
115
116 @Test
117 public void triggerProbe() {
118 // TODO
119 }
120
121 @Test
122 public void switchRemoved() {
123 controller.listener.switchRemoved(DPID1);
124 assertTrue("device not removed", registry.connected.isEmpty());
125 }
126
127 @Test
128 public void portChanged() {
129 OFPortStatus stat = SW1.factory().buildPortStatus()
130 .setReason(OFPortReason.ADD)
131 .setDesc(PD3)
132 .build();
133 controller.listener.portChanged(DPID1, stat);
Ayaka Koshibe39a04802014-09-22 10:23:54 -0700134 assertNotNull("never went throught the provider service", registry.descr);
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700135 assertEquals("port status unhandled", 3, registry.ports.get(DID1).size());
136 }
137
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700138 @Test
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700139 public void receivedRoleReply() {
140 // check translation capabilities
141 controller.listener.receivedRoleReply(DPID1, RoleState.MASTER, RoleState.MASTER);
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700142 assertEquals("wrong role reported", DPID1, registry.roles.get(MASTER));
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700143 controller.listener.receivedRoleReply(DPID1, RoleState.EQUAL, RoleState.MASTER);
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700144 assertEquals("wrong role reported", DPID1, registry.roles.get(STANDBY));
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700145 controller.listener.receivedRoleReply(DPID1, RoleState.SLAVE, RoleState.MASTER);
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700146 assertEquals("wrong role reported", DPID1, registry.roles.get(NONE));
147 }
148
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700149 private static OFPortDesc portDesc(int port) {
150 OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc();
151 builder.setPortNo(OFPort.of(port));
152
153 return builder.build();
154 }
155
156 private class TestDeviceRegistry implements DeviceProviderRegistry {
157 DeviceProvider provider;
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700158
159 Set<DeviceId> connected = new HashSet<>();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700160 Multimap<DeviceId, PortDescription> ports = HashMultimap.create();
Ayaka Koshibe39a04802014-09-22 10:23:54 -0700161 PortDescription descr = null;
Ayaka Koshibe32402f32014-09-25 11:08:54 -0700162 Map<MastershipRole, Dpid> roles = new HashMap<>();
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700163
164 @Override
165 public DeviceProviderService register(DeviceProvider provider) {
166 this.provider = provider;
167 return new TestProviderService();
168 }
169
170 @Override
171 public void unregister(DeviceProvider provider) {
172 }
173
174 @Override
175 public Set<ProviderId> getProviders() {
176 return null;
177 }
178
179 private class TestProviderService implements DeviceProviderService {
180
181 @Override
182 public DeviceProvider provider() {
183 return null;
184 }
185
186 @Override
187 public void deviceConnected(DeviceId deviceId,
188 DeviceDescription deviceDescription) {
189 connected.add(deviceId);
190 }
191
192 @Override
193 public void deviceDisconnected(DeviceId deviceId) {
194 connected.remove(deviceId);
195 ports.removeAll(deviceId);
196 }
197
198 @Override
199 public void updatePorts(DeviceId deviceId,
200 List<PortDescription> portDescriptions) {
201 for (PortDescription p : portDescriptions) {
202 ports.put(deviceId, p);
203 }
204 }
205
206 @Override
207 public void portStatusChanged(DeviceId deviceId,
208 PortDescription portDescription) {
Ayaka Koshibe39a04802014-09-22 10:23:54 -0700209 ports.put(deviceId, portDescription);
210 descr = portDescription;
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700211 }
212
tom3f2bbd72014-09-24 12:07:58 -0700213 @Override
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700214 public void receivedRoleReply(DeviceId deviceId,
215 MastershipRole requested, MastershipRole response) {
216 roles.put(requested, Dpid.dpid(deviceId.uri()));
tom3f2bbd72014-09-24 12:07:58 -0700217 }
218
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700219 }
220 }
221
222 private class TestController implements OpenFlowController {
223 OpenFlowSwitchListener listener = null;
224 Map<Dpid, RoleState> roleMap = new HashMap<Dpid, RoleState>();
225 Map<Dpid, OpenFlowSwitch> switchMap = new HashMap<Dpid, OpenFlowSwitch>();
226
227 @Override
228 public Iterable<OpenFlowSwitch> getSwitches() {
229 return switchMap.values();
230 }
231
232 @Override
233 public Iterable<OpenFlowSwitch> getMasterSwitches() {
234 return null;
235 }
236
237 @Override
238 public Iterable<OpenFlowSwitch> getEqualSwitches() {
239 return null;
240 }
241
242 @Override
243 public OpenFlowSwitch getSwitch(Dpid dpid) {
244 return switchMap.get(dpid);
245 }
246
247 @Override
248 public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
249 return null;
250 }
251
252 @Override
253 public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
254
255 return null;
256 }
257
258 @Override
259 public void addListener(OpenFlowSwitchListener listener) {
260 this.listener = listener;
261 }
262
263 @Override
264 public void removeListener(OpenFlowSwitchListener listener) {
265 this.listener = null;
266 }
267
268 @Override
269 public void addPacketListener(int priority, PacketListener listener) {
270 }
271
272 @Override
273 public void removePacketListener(PacketListener listener) {
274 }
275
276 @Override
277 public void addEventListener(OpenFlowEventListener listener) {
278 }
279
280 @Override
281 public void removeEventListener(OpenFlowEventListener listener) {
282 }
283
284 @Override
285 public void write(Dpid dpid, OFMessage msg) {
286 }
287
288 @Override
289 public void processPacket(Dpid dpid, OFMessage msg) {
290 }
291
292 @Override
293 public void setRole(Dpid dpid, RoleState role) {
294 roleMap.put(dpid, role);
295 }
296 }
297
298 private static class TestOpenFlowSwitch implements OpenFlowSwitch {
299
300 RoleState state;
301 List<OFMessage> sent = new ArrayList<OFMessage>();
302 OFFactory factory = OFFactoryVer10.INSTANCE;
303
304 @Override
305 public void sendMsg(OFMessage msg) {
306 sent.add(msg);
307 }
308
309 @Override
310 public void sendMsg(List<OFMessage> msgs) {
311 }
312
313 @Override
314 public void handleMessage(OFMessage fromSwitch) {
315 }
316
317 @Override
318 public void setRole(RoleState role) {
319 state = role;
320 }
321
322 @Override
323 public RoleState getRole() {
324 return state;
325 }
326
327 @Override
328 public List<OFPortDesc> getPorts() {
329 return PLIST;
330 }
331
332 @Override
333 public OFFactory factory() {
334 return factory;
335 }
336
337 @Override
338 public String getStringId() {
339 return null;
340 }
341
342 @Override
343 public long getId() {
344 return DPID1.value();
345 }
346
347 @Override
348 public String manfacturerDescription() {
349 return null;
350 }
351
352 @Override
353 public String datapathDescription() {
354 return null;
355 }
356
357 @Override
358 public String hardwareDescription() {
359 return null;
360 }
361
362 @Override
363 public String softwareDescription() {
364 return null;
365 }
366
367 @Override
368 public String serialNumber() {
369 return null;
370 }
371
372 @Override
Yuta HIGUCHI69a27352014-10-31 15:48:37 -0700373 public boolean isConnected() {
374 return true;
375 }
376
377 @Override
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700378 public void disconnectSwitch() {
379 }
380
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700381 @Override
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700382 public boolean isOptical() {
383 return false;
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700384 }
385
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700386 @Override
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700387 public void returnRoleReply(RoleState requested, RoleState reponse) {
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700388 }
389
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700390 }
391
392}