2 * Copyright 2014-2015 Open Networking Laboratory
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.onosproject.provider.of.device.impl;
18 import com.google.common.collect.HashMultimap;
19 import com.google.common.collect.Lists;
20 import com.google.common.collect.Multimap;
22 import org.junit.After;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.onosproject.cfg.ComponentConfigAdapter;
26 import org.onosproject.net.DefaultDevice;
27 import org.onosproject.net.Device;
28 import org.onosproject.net.DeviceId;
29 import org.onosproject.net.MastershipRole;
30 import org.onosproject.net.device.DeviceDescription;
31 import org.onosproject.net.device.DeviceProvider;
32 import org.onosproject.net.device.DeviceProviderRegistry;
33 import org.onosproject.net.device.DeviceProviderService;
34 import org.onosproject.net.device.PortDescription;
35 import org.onosproject.net.device.PortStatistics;
36 import org.onosproject.net.provider.ProviderId;
37 import org.onosproject.openflow.controller.Dpid;
38 import org.onosproject.openflow.controller.OpenFlowController;
39 import org.onosproject.openflow.controller.OpenFlowEventListener;
40 import org.onosproject.openflow.controller.OpenFlowSwitch;
41 import org.onosproject.openflow.controller.OpenFlowSwitchListener;
42 import org.onosproject.openflow.controller.PacketListener;
43 import org.onosproject.openflow.controller.RoleState;
44 import org.projectfloodlight.openflow.protocol.OFFactory;
45 import org.projectfloodlight.openflow.protocol.OFMessage;
46 import org.projectfloodlight.openflow.protocol.OFPortDesc;
47 import org.projectfloodlight.openflow.protocol.OFPortReason;
48 import org.projectfloodlight.openflow.protocol.OFPortStatus;
49 import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
50 import org.projectfloodlight.openflow.types.OFPort;
52 import java.util.ArrayList;
53 import java.util.Collection;
54 import java.util.HashMap;
55 import java.util.HashSet;
56 import java.util.List;
60 import static org.junit.Assert.*;
61 import static org.onosproject.net.Device.Type.SWITCH;
62 import static org.onosproject.net.MastershipRole.*;
64 public class OpenFlowDeviceProviderTest {
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());
70 private static final OFPortDesc PD1 = portDesc(1);
71 private static final OFPortDesc PD2 = portDesc(2);
72 private static final OFPortDesc PD3 = portDesc(3);
74 private static final List<OFPortDesc> PLIST = Lists.newArrayList(PD1, PD2);
76 private static final Device DEV1 =
77 new DefaultDevice(PID, DID1, SWITCH, "", "", "", "", null);
79 private static final TestOpenFlowSwitch SW1 = new TestOpenFlowSwitch();
81 private final OpenFlowDeviceProvider provider = new OpenFlowDeviceProvider();
82 private final TestDeviceRegistry registry = new TestDeviceRegistry();
83 private final TestController controller = new TestController();
86 public void startUp() {
87 provider.providerRegistry = registry;
88 provider.controller = controller;
89 provider.cfgService = new ComponentConfigAdapter();
90 controller.switchMap.put(DPID1, SW1);
91 provider.activate(null);
92 assertNotNull("provider should be registered", registry.provider);
93 assertNotNull("listener should be registered", controller.listener);
94 assertEquals("devices not added", 1, registry.connected.size());
95 assertEquals("ports not added", 2, registry.ports.get(DID1).size());
99 public void tearDown() {
100 provider.deactivate(null);
101 assertNull("listener should be removed", controller.listener);
102 provider.controller = null;
103 provider.providerRegistry = null;
107 public void roleChanged() {
108 provider.roleChanged(DID1, MASTER);
109 assertEquals("Should be MASTER", RoleState.MASTER, controller.roleMap.get(DPID1));
110 provider.roleChanged(DID1, STANDBY);
111 assertEquals("Should be EQUAL", RoleState.EQUAL, controller.roleMap.get(DPID1));
112 provider.roleChanged(DID1, NONE);
113 assertEquals("Should be SLAVE", RoleState.SLAVE, controller.roleMap.get(DPID1));
117 public void triggerProbe() {
122 public void switchRemoved() {
123 controller.listener.switchRemoved(DPID1);
124 assertTrue("device not removed", registry.connected.isEmpty());
128 public void portChanged() {
129 OFPortStatus stat = SW1.factory().buildPortStatus()
130 .setReason(OFPortReason.ADD)
133 controller.listener.portChanged(DPID1, stat);
134 assertNotNull("never went throught the provider service", registry.descr);
135 assertEquals("port status unhandled", 3, registry.ports.get(DID1).size());
139 public void receivedRoleReply() {
140 // check translation capabilities
141 controller.listener.receivedRoleReply(DPID1, RoleState.MASTER, RoleState.MASTER);
142 assertEquals("wrong role reported", DPID1, registry.roles.get(MASTER));
143 controller.listener.receivedRoleReply(DPID1, RoleState.EQUAL, RoleState.MASTER);
144 assertEquals("wrong role reported", DPID1, registry.roles.get(STANDBY));
145 controller.listener.receivedRoleReply(DPID1, RoleState.SLAVE, RoleState.MASTER);
146 assertEquals("wrong role reported", DPID1, registry.roles.get(NONE));
149 private static OFPortDesc portDesc(int port) {
150 OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc();
151 builder.setPortNo(OFPort.of(port));
153 return builder.build();
156 private class TestDeviceRegistry implements DeviceProviderRegistry {
157 DeviceProvider provider;
159 Set<DeviceId> connected = new HashSet<>();
160 Multimap<DeviceId, PortDescription> ports = HashMultimap.create();
161 PortDescription descr = null;
162 Map<MastershipRole, Dpid> roles = new HashMap<>();
165 public DeviceProviderService register(DeviceProvider provider) {
166 this.provider = provider;
167 return new TestProviderService();
171 public void unregister(DeviceProvider provider) {
175 public Set<ProviderId> getProviders() {
179 private class TestProviderService implements DeviceProviderService {
182 public DeviceProvider provider() {
187 public void deviceConnected(DeviceId deviceId,
188 DeviceDescription deviceDescription) {
189 connected.add(deviceId);
193 public void deviceDisconnected(DeviceId deviceId) {
194 connected.remove(deviceId);
195 ports.removeAll(deviceId);
199 public void updatePorts(DeviceId deviceId,
200 List<PortDescription> portDescriptions) {
201 for (PortDescription p : portDescriptions) {
202 ports.put(deviceId, p);
207 public void portStatusChanged(DeviceId deviceId,
208 PortDescription portDescription) {
209 ports.put(deviceId, portDescription);
210 descr = portDescription;
214 public void receivedRoleReply(DeviceId deviceId,
215 MastershipRole requested, MastershipRole response) {
216 roles.put(requested, Dpid.dpid(deviceId.uri()));
220 public void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics) {
227 private class TestController implements OpenFlowController {
228 OpenFlowSwitchListener listener = null;
229 Map<Dpid, RoleState> roleMap = new HashMap<Dpid, RoleState>();
230 Map<Dpid, OpenFlowSwitch> switchMap = new HashMap<Dpid, OpenFlowSwitch>();
233 public Iterable<OpenFlowSwitch> getSwitches() {
234 return switchMap.values();
238 public Iterable<OpenFlowSwitch> getMasterSwitches() {
243 public Iterable<OpenFlowSwitch> getEqualSwitches() {
248 public OpenFlowSwitch getSwitch(Dpid dpid) {
249 return switchMap.get(dpid);
253 public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
258 public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
264 public void addListener(OpenFlowSwitchListener listener) {
265 this.listener = listener;
269 public void removeListener(OpenFlowSwitchListener listener) {
270 this.listener = null;
274 public void addPacketListener(int priority, PacketListener listener) {
278 public void removePacketListener(PacketListener listener) {
282 public void addEventListener(OpenFlowEventListener listener) {
286 public void removeEventListener(OpenFlowEventListener listener) {
290 public void write(Dpid dpid, OFMessage msg) {
294 public void processPacket(Dpid dpid, OFMessage msg) {
298 public void setRole(Dpid dpid, RoleState role) {
299 roleMap.put(dpid, role);
303 private static class TestOpenFlowSwitch implements OpenFlowSwitch {
306 List<OFMessage> sent = new ArrayList<OFMessage>();
307 OFFactory factory = OFFactoryVer10.INSTANCE;
310 public void sendMsg(OFMessage msg) {
315 public void sendMsg(List<OFMessage> msgs) {
319 public void handleMessage(OFMessage fromSwitch) {
323 public void setRole(RoleState role) {
328 public RoleState getRole() {
333 public List<OFPortDesc> getPorts() {
338 public OFFactory factory() {
343 public String getStringId() {
348 public long getId() {
349 return DPID1.value();
353 public String manufacturerDescription() {
358 public String datapathDescription() {
363 public String hardwareDescription() {
368 public String softwareDescription() {
373 public String serialNumber() {
378 public boolean isConnected() {
383 public void disconnectSwitch() {
387 public Device.Type deviceType() {
388 return Device.Type.SWITCH;
392 public void returnRoleReply(RoleState requested, RoleState response) {
396 public String channelId() {