blob: a86502fa7bb9b065df8c39a287fa35d45ca93382 [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;
Ayaka Koshibec4047702014-10-07 14:43:52 -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;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070013import org.onlab.onos.cluster.NodeId;
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070014import org.onlab.onos.cluster.ControllerNode.State;
tome5ec3fd2014-09-04 15:18:06 -070015import org.onlab.onos.event.Event;
tomb41d1ac2014-09-24 01:51:24 -070016import org.onlab.onos.event.impl.TestEventDispatcher;
Yuta HIGUCHI80912e62014-10-12 00:15:47 -070017import org.onlab.onos.mastership.MastershipServiceAdapter;
18import org.onlab.onos.mastership.MastershipTerm;
19import org.onlab.onos.mastership.MastershipTermService;
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;
Yuta HIGUCHI093e83e2014-10-10 22:26:11 -070028import org.onlab.onos.net.device.DeviceClockProviderService;
tome5ec3fd2014-09-04 15:18:06 -070029import org.onlab.onos.net.device.DeviceDescription;
30import org.onlab.onos.net.device.DeviceEvent;
31import org.onlab.onos.net.device.DeviceListener;
32import org.onlab.onos.net.device.DeviceProvider;
33import org.onlab.onos.net.device.DeviceProviderRegistry;
34import org.onlab.onos.net.device.DeviceProviderService;
35import org.onlab.onos.net.device.DeviceService;
tom24c55cd2014-09-06 10:47:25 -070036import org.onlab.onos.net.device.PortDescription;
tome5ec3fd2014-09-04 15:18:06 -070037import org.onlab.onos.net.provider.AbstractProvider;
38import org.onlab.onos.net.provider.ProviderId;
tomea961ff2014-10-01 12:45:15 -070039import org.onlab.onos.store.trivial.impl.SimpleDeviceStore;
alshabib7911a052014-10-16 17:49:37 -070040import org.onlab.packet.ChassisId;
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070041import org.onlab.packet.IpPrefix;
tome5ec3fd2014-09-04 15:18:06 -070042
43import java.util.ArrayList;
44import java.util.Iterator;
45import java.util.List;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070046import java.util.Set;
tome5ec3fd2014-09-04 15:18:06 -070047
48import static org.junit.Assert.*;
49import static org.onlab.onos.net.Device.Type.SWITCH;
50import static org.onlab.onos.net.DeviceId.deviceId;
51import static org.onlab.onos.net.device.DeviceEvent.Type.*;
52
53/**
54 * Test codifying the device service & device provider service contracts.
55 */
tom41a2c5f2014-09-19 09:20:35 -070056public class DeviceManagerTest {
tome5ec3fd2014-09-04 15:18:06 -070057
tom7e02cda2014-09-18 12:05:46 -070058 private static final ProviderId PID = new ProviderId("of", "foo");
tome5ec3fd2014-09-04 15:18:06 -070059 private static final DeviceId DID1 = deviceId("of:foo");
60 private static final DeviceId DID2 = deviceId("of:bar");
61 private static final String MFR = "whitebox";
62 private static final String HW = "1.1.x";
63 private static final String SW1 = "3.8.1";
64 private static final String SW2 = "3.9.5";
65 private static final String SN = "43311-12345";
alshabib7911a052014-10-16 17:49:37 -070066 private static final ChassisId CID = new ChassisId();
tome5ec3fd2014-09-04 15:18:06 -070067
tom24c55cd2014-09-06 10:47:25 -070068 private static final PortNumber P1 = PortNumber.portNumber(1);
69 private static final PortNumber P2 = PortNumber.portNumber(2);
70 private static final PortNumber P3 = PortNumber.portNumber(3);
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070071 private static final NodeId NID_LOCAL = new NodeId("local");
72 private static final IpPrefix LOCALHOST = IpPrefix.valueOf("127.0.0.1");
tom24c55cd2014-09-06 10:47:25 -070073
tom41a2c5f2014-09-19 09:20:35 -070074 private DeviceManager mgr;
tome5ec3fd2014-09-04 15:18:06 -070075
76 protected DeviceService service;
77 protected DeviceAdminService admin;
78 protected DeviceProviderRegistry registry;
79 protected DeviceProviderService providerService;
80 protected TestProvider provider;
81 protected TestListener listener = new TestListener();
82
83 @Before
84 public void setUp() {
tom41a2c5f2014-09-19 09:20:35 -070085 mgr = new DeviceManager();
tome5ec3fd2014-09-04 15:18:06 -070086 service = mgr;
87 admin = mgr;
88 registry = mgr;
tom41a2c5f2014-09-19 09:20:35 -070089 mgr.store = new SimpleDeviceStore();
tome5ec3fd2014-09-04 15:18:06 -070090 mgr.eventDispatcher = new TestEventDispatcher();
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070091 mgr.mastershipService = new TestMastershipService();
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070092 mgr.clusterService = new TestClusterService();
Yuta HIGUCHI093e83e2014-10-10 22:26:11 -070093 mgr.deviceClockProviderService = new TestClockProviderService();
tome5ec3fd2014-09-04 15:18:06 -070094 mgr.activate();
95
96 service.addListener(listener);
97
98 provider = new TestProvider();
99 providerService = registry.register(provider);
100 assertTrue("provider should be registered",
101 registry.getProviders().contains(provider.id()));
102 }
103
104 @After
105 public void tearDown() {
106 registry.unregister(provider);
107 assertFalse("provider should not be registered",
108 registry.getProviders().contains(provider.id()));
109 service.removeListener(listener);
110 mgr.deactivate();
111 }
112
113 private void connectDevice(DeviceId deviceId, String swVersion) {
114 DeviceDescription description =
115 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
alshabib7911a052014-10-16 17:49:37 -0700116 HW, swVersion, SN, CID);
tome5ec3fd2014-09-04 15:18:06 -0700117 providerService.deviceConnected(deviceId, description);
118 assertNotNull("device should be found", service.getDevice(DID1));
119 }
120
121 @Test
122 public void deviceConnected() {
123 assertNull("device should not be found", service.getDevice(DID1));
124 connectDevice(DID1, SW1);
125 validateEvents(DEVICE_ADDED);
126
127 Iterator<Device> it = service.getDevices().iterator();
128 assertNotNull("one device expected", it.next());
129 assertFalse("only one device expected", it.hasNext());
tomad2d2092014-09-06 23:24:20 -0700130 assertEquals("incorrect device count", 1, service.getDeviceCount());
tomff7eb7c2014-09-08 12:49:03 -0700131 assertTrue("device should be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700132 }
133
134 @Test
135 public void deviceDisconnected() {
136 connectDevice(DID1, SW1);
137 connectDevice(DID2, SW1);
138 validateEvents(DEVICE_ADDED, DEVICE_ADDED);
tomff7eb7c2014-09-08 12:49:03 -0700139 assertTrue("device should be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700140
141 // Disconnect
142 providerService.deviceDisconnected(DID1);
143 assertNotNull("device should not be found", service.getDevice(DID1));
tomff7eb7c2014-09-08 12:49:03 -0700144 assertFalse("device should not be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700145 validateEvents(DEVICE_AVAILABILITY_CHANGED);
146
147 // Reconnect
148 connectDevice(DID1, SW1);
149 validateEvents(DEVICE_AVAILABILITY_CHANGED);
tomad2d2092014-09-06 23:24:20 -0700150
151 assertEquals("incorrect device count", 2, service.getDeviceCount());
tome5ec3fd2014-09-04 15:18:06 -0700152 }
153
154 @Test
155 public void deviceUpdated() {
156 connectDevice(DID1, SW1);
157 validateEvents(DEVICE_ADDED);
158
159 connectDevice(DID1, SW2);
160 validateEvents(DEVICE_UPDATED);
161 }
162
163 @Test
164 public void getRole() {
165 connectDevice(DID1, SW1);
tom80c0e5e2014-09-08 18:08:58 -0700166 assertEquals("incorrect role", MastershipRole.MASTER, service.getRole(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700167 }
168
tomb41d1ac2014-09-24 01:51:24 -0700169 @Ignore("disabled until we settle the device-mastership wiring")
tome5ec3fd2014-09-04 15:18:06 -0700170 @Test
tom5f35f7c2014-09-08 18:38:19 -0700171 public void setRole() throws InterruptedException {
tome5ec3fd2014-09-04 15:18:06 -0700172 connectDevice(DID1, SW1);
tome5ec3fd2014-09-04 15:18:06 -0700173 validateEvents(DEVICE_ADDED, DEVICE_MASTERSHIP_CHANGED);
tom80c0e5e2014-09-08 18:08:58 -0700174 assertEquals("incorrect role", MastershipRole.STANDBY, service.getRole(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700175 assertEquals("incorrect device", DID1, provider.deviceReceived.id());
tom80c0e5e2014-09-08 18:08:58 -0700176 assertEquals("incorrect role", MastershipRole.STANDBY, provider.roleReceived);
tome5ec3fd2014-09-04 15:18:06 -0700177 }
178
tom24c55cd2014-09-06 10:47:25 -0700179 @Test
180 public void updatePorts() {
181 connectDevice(DID1, SW1);
182 List<PortDescription> pds = new ArrayList<>();
183 pds.add(new DefaultPortDescription(P1, true));
184 pds.add(new DefaultPortDescription(P2, true));
185 pds.add(new DefaultPortDescription(P3, true));
186 providerService.updatePorts(DID1, pds);
187 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED);
188 pds.clear();
tome5ec3fd2014-09-04 15:18:06 -0700189
tom24c55cd2014-09-06 10:47:25 -0700190 pds.add(new DefaultPortDescription(P1, false));
191 pds.add(new DefaultPortDescription(P3, true));
192 providerService.updatePorts(DID1, pds);
193 validateEvents(PORT_UPDATED, PORT_REMOVED);
194 }
195
196 @Test
197 public void updatePortStatus() {
198 connectDevice(DID1, SW1);
199 List<PortDescription> pds = new ArrayList<>();
200 pds.add(new DefaultPortDescription(P1, true));
201 pds.add(new DefaultPortDescription(P2, true));
202 providerService.updatePorts(DID1, pds);
203 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
204
205 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
206 validateEvents(PORT_UPDATED);
207 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
208 assertTrue("no events expected", listener.events.isEmpty());
209 }
210
211 @Test
212 public void getPorts() {
213 connectDevice(DID1, SW1);
214 List<PortDescription> pds = new ArrayList<>();
215 pds.add(new DefaultPortDescription(P1, true));
216 pds.add(new DefaultPortDescription(P2, true));
217 providerService.updatePorts(DID1, pds);
218 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
219 assertEquals("wrong port count", 2, service.getPorts(DID1).size());
220
221 Port port = service.getPort(DID1, P1);
222 assertEquals("incorrect port", P1, service.getPort(DID1, P1).number());
223 assertEquals("incorrect state", true, service.getPort(DID1, P1).isEnabled());
224 }
225
226 @Test
227 public void removeDevice() {
228 connectDevice(DID1, SW1);
229 connectDevice(DID2, SW2);
tomad2d2092014-09-06 23:24:20 -0700230 assertEquals("incorrect device count", 2, service.getDeviceCount());
tom24c55cd2014-09-06 10:47:25 -0700231 admin.removeDevice(DID1);
232 assertNull("device should not be found", service.getDevice(DID1));
233 assertNotNull("device should be found", service.getDevice(DID2));
tomad2d2092014-09-06 23:24:20 -0700234 assertEquals("incorrect device count", 1, service.getDeviceCount());
235
tom24c55cd2014-09-06 10:47:25 -0700236 }
tome5ec3fd2014-09-04 15:18:06 -0700237
238 protected void validateEvents(Enum... types) {
239 int i = 0;
240 assertEquals("wrong events received", types.length, listener.events.size());
241 for (Event event : listener.events) {
242 assertEquals("incorrect event type", types[i], event.type());
243 i++;
244 }
245 listener.events.clear();
246 }
247
248
249 private class TestProvider extends AbstractProvider implements DeviceProvider {
250 private Device deviceReceived;
251 private MastershipRole roleReceived;
252
253 public TestProvider() {
254 super(PID);
255 }
256
257 @Override
258 public void triggerProbe(Device device) {
259 }
260
261 @Override
262 public void roleChanged(Device device, MastershipRole newRole) {
263 deviceReceived = device;
264 roleReceived = newRole;
265 }
266 }
267
268 private static class TestListener implements DeviceListener {
269 final List<DeviceEvent> events = new ArrayList<>();
270
271 @Override
272 public void event(DeviceEvent event) {
273 events.add(event);
274 }
275 }
276
Ayaka Koshibec4047702014-10-07 14:43:52 -0700277 private static class TestMastershipService
278 extends MastershipServiceAdapter {
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700279 @Override
tomb41d1ac2014-09-24 01:51:24 -0700280 public MastershipRole getLocalRole(DeviceId deviceId) {
281 return MastershipRole.MASTER;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700282 }
283
284 @Override
285 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
286 return Sets.newHashSet(DID1, DID2);
287 }
288
289 @Override
290 public MastershipRole requestRoleFor(DeviceId deviceId) {
291 return MastershipRole.MASTER;
292 }
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700293
294 @Override
295 public MastershipTermService requestTermService() {
296 return new MastershipTermService() {
297 @Override
298 public MastershipTerm getMastershipTerm(DeviceId deviceId) {
299 // FIXME: just returning something not null
300 return MastershipTerm.of(NID_LOCAL, 1);
301 }
302 };
303 }
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700304 }
305
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700306 // code clone
307 private final class TestClusterService implements ClusterService {
308
309 ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST);
310
311 @Override
312 public ControllerNode getLocalNode() {
313 return local;
314 }
315
316 @Override
317 public Set<ControllerNode> getNodes() {
318 return null;
319 }
320
321 @Override
322 public ControllerNode getNode(NodeId nodeId) {
323 return null;
324 }
325
326 @Override
327 public State getState(NodeId nodeId) {
328 return null;
329 }
330
331 @Override
332 public void addListener(ClusterEventListener listener) {
333 }
334
335 @Override
336 public void removeListener(ClusterEventListener listener) {
337 }
338 }
339
340 private final class TestClockProviderService implements
Yuta HIGUCHI093e83e2014-10-10 22:26:11 -0700341 DeviceClockProviderService {
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700342
343 @Override
344 public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) {
345 // TODO Auto-generated method stub
346 }
347 }
tome5ec3fd2014-09-04 15:18:06 -0700348}