blob: 2cd6919946fb99b584f8ee7476806bf66db416e4 [file] [log] [blame]
tombe988312014-09-19 18:38:47 -07001package org.onlab.onos.net.device.impl;
tome5ec3fd2014-09-04 15:18:06 -07002
tomb41d1ac2014-09-24 01:51:24 -07003import com.google.common.collect.Sets;
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -07004
tome5ec3fd2014-09-04 15:18:06 -07005import org.junit.After;
6import org.junit.Before;
tomb41d1ac2014-09-24 01:51:24 -07007import org.junit.Ignore;
tome5ec3fd2014-09-04 15:18:06 -07008import org.junit.Test;
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -07009import org.onlab.onos.cluster.ClusterEventListener;
10import org.onlab.onos.cluster.ClusterService;
11import org.onlab.onos.cluster.ControllerNode;
12import org.onlab.onos.cluster.DefaultControllerNode;
tomb41d1ac2014-09-24 01:51:24 -070013import org.onlab.onos.cluster.MastershipServiceAdapter;
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070014import org.onlab.onos.cluster.MastershipTerm;
15import org.onlab.onos.cluster.MastershipTermService;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070016import org.onlab.onos.cluster.NodeId;
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070017import org.onlab.onos.cluster.ControllerNode.State;
tome5ec3fd2014-09-04 15:18:06 -070018import org.onlab.onos.event.Event;
tomb41d1ac2014-09-24 01:51:24 -070019import org.onlab.onos.event.impl.TestEventDispatcher;
tome5ec3fd2014-09-04 15:18:06 -070020import org.onlab.onos.net.Device;
21import org.onlab.onos.net.DeviceId;
22import org.onlab.onos.net.MastershipRole;
tom24c55cd2014-09-06 10:47:25 -070023import org.onlab.onos.net.Port;
24import org.onlab.onos.net.PortNumber;
tome5ec3fd2014-09-04 15:18:06 -070025import org.onlab.onos.net.device.DefaultDeviceDescription;
tom24c55cd2014-09-06 10:47:25 -070026import org.onlab.onos.net.device.DefaultPortDescription;
tome5ec3fd2014-09-04 15:18:06 -070027import org.onlab.onos.net.device.DeviceAdminService;
28import org.onlab.onos.net.device.DeviceDescription;
29import org.onlab.onos.net.device.DeviceEvent;
30import org.onlab.onos.net.device.DeviceListener;
31import org.onlab.onos.net.device.DeviceProvider;
32import org.onlab.onos.net.device.DeviceProviderRegistry;
33import org.onlab.onos.net.device.DeviceProviderService;
34import org.onlab.onos.net.device.DeviceService;
tom24c55cd2014-09-06 10:47:25 -070035import org.onlab.onos.net.device.PortDescription;
tome5ec3fd2014-09-04 15:18:06 -070036import org.onlab.onos.net.provider.AbstractProvider;
37import org.onlab.onos.net.provider.ProviderId;
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070038import org.onlab.onos.store.ClockProviderService;
tomea961ff2014-10-01 12:45:15 -070039import org.onlab.onos.store.trivial.impl.SimpleDeviceStore;
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070040import org.onlab.packet.IpPrefix;
tome5ec3fd2014-09-04 15:18:06 -070041
42import java.util.ArrayList;
43import java.util.Iterator;
44import java.util.List;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070045import java.util.Set;
tome5ec3fd2014-09-04 15:18:06 -070046
47import static org.junit.Assert.*;
48import static org.onlab.onos.net.Device.Type.SWITCH;
49import static org.onlab.onos.net.DeviceId.deviceId;
50import static org.onlab.onos.net.device.DeviceEvent.Type.*;
51
52/**
53 * Test codifying the device service & device provider service contracts.
54 */
tom41a2c5f2014-09-19 09:20:35 -070055public class DeviceManagerTest {
tome5ec3fd2014-09-04 15:18:06 -070056
tom7e02cda2014-09-18 12:05:46 -070057 private static final ProviderId PID = new ProviderId("of", "foo");
tome5ec3fd2014-09-04 15:18:06 -070058 private static final DeviceId DID1 = deviceId("of:foo");
59 private static final DeviceId DID2 = deviceId("of:bar");
60 private static final String MFR = "whitebox";
61 private static final String HW = "1.1.x";
62 private static final String SW1 = "3.8.1";
63 private static final String SW2 = "3.9.5";
64 private static final String SN = "43311-12345";
65
tom24c55cd2014-09-06 10:47:25 -070066 private static final PortNumber P1 = PortNumber.portNumber(1);
67 private static final PortNumber P2 = PortNumber.portNumber(2);
68 private static final PortNumber P3 = PortNumber.portNumber(3);
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070069 private static final NodeId NID_LOCAL = new NodeId("local");
70 private static final IpPrefix LOCALHOST = IpPrefix.valueOf("127.0.0.1");
tom24c55cd2014-09-06 10:47:25 -070071
tom41a2c5f2014-09-19 09:20:35 -070072 private DeviceManager mgr;
tome5ec3fd2014-09-04 15:18:06 -070073
74 protected DeviceService service;
75 protected DeviceAdminService admin;
76 protected DeviceProviderRegistry registry;
77 protected DeviceProviderService providerService;
78 protected TestProvider provider;
79 protected TestListener listener = new TestListener();
80
81 @Before
82 public void setUp() {
tom41a2c5f2014-09-19 09:20:35 -070083 mgr = new DeviceManager();
tome5ec3fd2014-09-04 15:18:06 -070084 service = mgr;
85 admin = mgr;
86 registry = mgr;
tom41a2c5f2014-09-19 09:20:35 -070087 mgr.store = new SimpleDeviceStore();
tome5ec3fd2014-09-04 15:18:06 -070088 mgr.eventDispatcher = new TestEventDispatcher();
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070089 mgr.mastershipService = new TestMastershipService();
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070090 mgr.clusterService = new TestClusterService();
91 mgr.clockProviderService = new TestClockProviderService();
tome5ec3fd2014-09-04 15:18:06 -070092 mgr.activate();
93
94 service.addListener(listener);
95
96 provider = new TestProvider();
97 providerService = registry.register(provider);
98 assertTrue("provider should be registered",
99 registry.getProviders().contains(provider.id()));
100 }
101
102 @After
103 public void tearDown() {
104 registry.unregister(provider);
105 assertFalse("provider should not be registered",
106 registry.getProviders().contains(provider.id()));
107 service.removeListener(listener);
108 mgr.deactivate();
109 }
110
111 private void connectDevice(DeviceId deviceId, String swVersion) {
112 DeviceDescription description =
113 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
114 HW, swVersion, SN);
115 providerService.deviceConnected(deviceId, description);
116 assertNotNull("device should be found", service.getDevice(DID1));
117 }
118
119 @Test
120 public void deviceConnected() {
121 assertNull("device should not be found", service.getDevice(DID1));
122 connectDevice(DID1, SW1);
123 validateEvents(DEVICE_ADDED);
124
125 Iterator<Device> it = service.getDevices().iterator();
126 assertNotNull("one device expected", it.next());
127 assertFalse("only one device expected", it.hasNext());
tomad2d2092014-09-06 23:24:20 -0700128 assertEquals("incorrect device count", 1, service.getDeviceCount());
tomff7eb7c2014-09-08 12:49:03 -0700129 assertTrue("device should be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700130 }
131
132 @Test
133 public void deviceDisconnected() {
134 connectDevice(DID1, SW1);
135 connectDevice(DID2, SW1);
136 validateEvents(DEVICE_ADDED, DEVICE_ADDED);
tomff7eb7c2014-09-08 12:49:03 -0700137 assertTrue("device should be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700138
139 // Disconnect
140 providerService.deviceDisconnected(DID1);
141 assertNotNull("device should not be found", service.getDevice(DID1));
tomff7eb7c2014-09-08 12:49:03 -0700142 assertFalse("device should not be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700143 validateEvents(DEVICE_AVAILABILITY_CHANGED);
144
145 // Reconnect
146 connectDevice(DID1, SW1);
147 validateEvents(DEVICE_AVAILABILITY_CHANGED);
tomad2d2092014-09-06 23:24:20 -0700148
149 assertEquals("incorrect device count", 2, service.getDeviceCount());
tome5ec3fd2014-09-04 15:18:06 -0700150 }
151
152 @Test
153 public void deviceUpdated() {
154 connectDevice(DID1, SW1);
155 validateEvents(DEVICE_ADDED);
156
157 connectDevice(DID1, SW2);
158 validateEvents(DEVICE_UPDATED);
159 }
160
161 @Test
162 public void getRole() {
163 connectDevice(DID1, SW1);
tom80c0e5e2014-09-08 18:08:58 -0700164 assertEquals("incorrect role", MastershipRole.MASTER, service.getRole(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700165 }
166
tomb41d1ac2014-09-24 01:51:24 -0700167 @Ignore("disabled until we settle the device-mastership wiring")
tome5ec3fd2014-09-04 15:18:06 -0700168 @Test
tom5f35f7c2014-09-08 18:38:19 -0700169 public void setRole() throws InterruptedException {
tome5ec3fd2014-09-04 15:18:06 -0700170 connectDevice(DID1, SW1);
tome5ec3fd2014-09-04 15:18:06 -0700171 validateEvents(DEVICE_ADDED, DEVICE_MASTERSHIP_CHANGED);
tom80c0e5e2014-09-08 18:08:58 -0700172 assertEquals("incorrect role", MastershipRole.STANDBY, service.getRole(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700173 assertEquals("incorrect device", DID1, provider.deviceReceived.id());
tom80c0e5e2014-09-08 18:08:58 -0700174 assertEquals("incorrect role", MastershipRole.STANDBY, provider.roleReceived);
tome5ec3fd2014-09-04 15:18:06 -0700175 }
176
tom24c55cd2014-09-06 10:47:25 -0700177 @Test
178 public void updatePorts() {
179 connectDevice(DID1, SW1);
180 List<PortDescription> pds = new ArrayList<>();
181 pds.add(new DefaultPortDescription(P1, true));
182 pds.add(new DefaultPortDescription(P2, true));
183 pds.add(new DefaultPortDescription(P3, true));
184 providerService.updatePorts(DID1, pds);
185 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED);
186 pds.clear();
tome5ec3fd2014-09-04 15:18:06 -0700187
tom24c55cd2014-09-06 10:47:25 -0700188 pds.add(new DefaultPortDescription(P1, false));
189 pds.add(new DefaultPortDescription(P3, true));
190 providerService.updatePorts(DID1, pds);
191 validateEvents(PORT_UPDATED, PORT_REMOVED);
192 }
193
194 @Test
195 public void updatePortStatus() {
196 connectDevice(DID1, SW1);
197 List<PortDescription> pds = new ArrayList<>();
198 pds.add(new DefaultPortDescription(P1, true));
199 pds.add(new DefaultPortDescription(P2, true));
200 providerService.updatePorts(DID1, pds);
201 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
202
203 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
204 validateEvents(PORT_UPDATED);
205 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
206 assertTrue("no events expected", listener.events.isEmpty());
207 }
208
209 @Test
210 public void getPorts() {
211 connectDevice(DID1, SW1);
212 List<PortDescription> pds = new ArrayList<>();
213 pds.add(new DefaultPortDescription(P1, true));
214 pds.add(new DefaultPortDescription(P2, true));
215 providerService.updatePorts(DID1, pds);
216 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
217 assertEquals("wrong port count", 2, service.getPorts(DID1).size());
218
219 Port port = service.getPort(DID1, P1);
220 assertEquals("incorrect port", P1, service.getPort(DID1, P1).number());
221 assertEquals("incorrect state", true, service.getPort(DID1, P1).isEnabled());
222 }
223
224 @Test
225 public void removeDevice() {
226 connectDevice(DID1, SW1);
227 connectDevice(DID2, SW2);
tomad2d2092014-09-06 23:24:20 -0700228 assertEquals("incorrect device count", 2, service.getDeviceCount());
tom24c55cd2014-09-06 10:47:25 -0700229 admin.removeDevice(DID1);
230 assertNull("device should not be found", service.getDevice(DID1));
231 assertNotNull("device should be found", service.getDevice(DID2));
tomad2d2092014-09-06 23:24:20 -0700232 assertEquals("incorrect device count", 1, service.getDeviceCount());
233
tom24c55cd2014-09-06 10:47:25 -0700234 }
tome5ec3fd2014-09-04 15:18:06 -0700235
236 protected void validateEvents(Enum... types) {
237 int i = 0;
238 assertEquals("wrong events received", types.length, listener.events.size());
239 for (Event event : listener.events) {
240 assertEquals("incorrect event type", types[i], event.type());
241 i++;
242 }
243 listener.events.clear();
244 }
245
246
247 private class TestProvider extends AbstractProvider implements DeviceProvider {
248 private Device deviceReceived;
249 private MastershipRole roleReceived;
250
251 public TestProvider() {
252 super(PID);
253 }
254
255 @Override
256 public void triggerProbe(Device device) {
257 }
258
259 @Override
260 public void roleChanged(Device device, MastershipRole newRole) {
261 deviceReceived = device;
262 roleReceived = newRole;
263 }
264 }
265
266 private static class TestListener implements DeviceListener {
267 final List<DeviceEvent> events = new ArrayList<>();
268
269 @Override
270 public void event(DeviceEvent event) {
271 events.add(event);
272 }
273 }
274
tomb41d1ac2014-09-24 01:51:24 -0700275 private static class TestMastershipService extends MastershipServiceAdapter {
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700276 @Override
tomb41d1ac2014-09-24 01:51:24 -0700277 public MastershipRole getLocalRole(DeviceId deviceId) {
278 return MastershipRole.MASTER;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700279 }
280
281 @Override
282 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
283 return Sets.newHashSet(DID1, DID2);
284 }
285
286 @Override
287 public MastershipRole requestRoleFor(DeviceId deviceId) {
288 return MastershipRole.MASTER;
289 }
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700290
291 @Override
292 public MastershipTermService requestTermService() {
293 return new MastershipTermService() {
294 @Override
295 public MastershipTerm getMastershipTerm(DeviceId deviceId) {
296 // FIXME: just returning something not null
297 return MastershipTerm.of(NID_LOCAL, 1);
298 }
299 };
300 }
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700301 }
302
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700303 // code clone
304 private final class TestClusterService implements ClusterService {
305
306 ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST);
307
308 @Override
309 public ControllerNode getLocalNode() {
310 return local;
311 }
312
313 @Override
314 public Set<ControllerNode> getNodes() {
315 return null;
316 }
317
318 @Override
319 public ControllerNode getNode(NodeId nodeId) {
320 return null;
321 }
322
323 @Override
324 public State getState(NodeId nodeId) {
325 return null;
326 }
327
328 @Override
329 public void addListener(ClusterEventListener listener) {
330 }
331
332 @Override
333 public void removeListener(ClusterEventListener listener) {
334 }
335 }
336
337 private final class TestClockProviderService implements
338 ClockProviderService {
339
340 @Override
341 public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) {
342 // TODO Auto-generated method stub
343 }
344 }
tome5ec3fd2014-09-04 15:18:06 -0700345}