blob: d07937844c1fa0474fe470ac8ca7f11ee8f7f61c [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
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
7 *
8 * 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.
15 */
tombe988312014-09-19 18:38:47 -070016package org.onlab.onos.net.device.impl;
tome5ec3fd2014-09-04 15:18:06 -070017
tomb41d1ac2014-09-24 01:51:24 -070018import com.google.common.collect.Sets;
Ayaka Koshibec4047702014-10-07 14:43:52 -070019
tome5ec3fd2014-09-04 15:18:06 -070020import org.junit.After;
21import org.junit.Before;
tomb41d1ac2014-09-24 01:51:24 -070022import org.junit.Ignore;
tome5ec3fd2014-09-04 15:18:06 -070023import org.junit.Test;
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070024import org.onlab.onos.cluster.ClusterEventListener;
25import org.onlab.onos.cluster.ClusterService;
26import org.onlab.onos.cluster.ControllerNode;
27import org.onlab.onos.cluster.DefaultControllerNode;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070028import org.onlab.onos.cluster.NodeId;
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070029import org.onlab.onos.cluster.ControllerNode.State;
tome5ec3fd2014-09-04 15:18:06 -070030import org.onlab.onos.event.Event;
tomb41d1ac2014-09-24 01:51:24 -070031import org.onlab.onos.event.impl.TestEventDispatcher;
Yuta HIGUCHI80912e62014-10-12 00:15:47 -070032import org.onlab.onos.mastership.MastershipServiceAdapter;
33import org.onlab.onos.mastership.MastershipTerm;
34import org.onlab.onos.mastership.MastershipTermService;
tome5ec3fd2014-09-04 15:18:06 -070035import org.onlab.onos.net.Device;
36import org.onlab.onos.net.DeviceId;
37import org.onlab.onos.net.MastershipRole;
tom24c55cd2014-09-06 10:47:25 -070038import org.onlab.onos.net.Port;
39import org.onlab.onos.net.PortNumber;
tome5ec3fd2014-09-04 15:18:06 -070040import org.onlab.onos.net.device.DefaultDeviceDescription;
tom24c55cd2014-09-06 10:47:25 -070041import org.onlab.onos.net.device.DefaultPortDescription;
tome5ec3fd2014-09-04 15:18:06 -070042import org.onlab.onos.net.device.DeviceAdminService;
Yuta HIGUCHI093e83e2014-10-10 22:26:11 -070043import org.onlab.onos.net.device.DeviceClockProviderService;
tome5ec3fd2014-09-04 15:18:06 -070044import org.onlab.onos.net.device.DeviceDescription;
45import org.onlab.onos.net.device.DeviceEvent;
46import org.onlab.onos.net.device.DeviceListener;
47import org.onlab.onos.net.device.DeviceProvider;
48import org.onlab.onos.net.device.DeviceProviderRegistry;
49import org.onlab.onos.net.device.DeviceProviderService;
50import org.onlab.onos.net.device.DeviceService;
tom24c55cd2014-09-06 10:47:25 -070051import org.onlab.onos.net.device.PortDescription;
tome5ec3fd2014-09-04 15:18:06 -070052import org.onlab.onos.net.provider.AbstractProvider;
53import org.onlab.onos.net.provider.ProviderId;
tomea961ff2014-10-01 12:45:15 -070054import org.onlab.onos.store.trivial.impl.SimpleDeviceStore;
alshabib7911a052014-10-16 17:49:37 -070055import org.onlab.packet.ChassisId;
Pavlin Radoslavov444b5192014-10-28 10:45:19 -070056import org.onlab.packet.IpAddress;
tome5ec3fd2014-09-04 15:18:06 -070057
58import java.util.ArrayList;
59import java.util.Iterator;
60import java.util.List;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -070061import java.util.Set;
tome5ec3fd2014-09-04 15:18:06 -070062
63import static org.junit.Assert.*;
64import static org.onlab.onos.net.Device.Type.SWITCH;
65import static org.onlab.onos.net.DeviceId.deviceId;
66import static org.onlab.onos.net.device.DeviceEvent.Type.*;
67
68/**
69 * Test codifying the device service & device provider service contracts.
70 */
tom41a2c5f2014-09-19 09:20:35 -070071public class DeviceManagerTest {
tome5ec3fd2014-09-04 15:18:06 -070072
tom7e02cda2014-09-18 12:05:46 -070073 private static final ProviderId PID = new ProviderId("of", "foo");
tome5ec3fd2014-09-04 15:18:06 -070074 private static final DeviceId DID1 = deviceId("of:foo");
75 private static final DeviceId DID2 = deviceId("of:bar");
76 private static final String MFR = "whitebox";
77 private static final String HW = "1.1.x";
78 private static final String SW1 = "3.8.1";
79 private static final String SW2 = "3.9.5";
80 private static final String SN = "43311-12345";
alshabib7911a052014-10-16 17:49:37 -070081 private static final ChassisId CID = new ChassisId();
tome5ec3fd2014-09-04 15:18:06 -070082
tom24c55cd2014-09-06 10:47:25 -070083 private static final PortNumber P1 = PortNumber.portNumber(1);
84 private static final PortNumber P2 = PortNumber.portNumber(2);
85 private static final PortNumber P3 = PortNumber.portNumber(3);
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070086 private static final NodeId NID_LOCAL = new NodeId("local");
Pavlin Radoslavov444b5192014-10-28 10:45:19 -070087 private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
tom24c55cd2014-09-06 10:47:25 -070088
tom41a2c5f2014-09-19 09:20:35 -070089 private DeviceManager mgr;
tome5ec3fd2014-09-04 15:18:06 -070090
91 protected DeviceService service;
92 protected DeviceAdminService admin;
93 protected DeviceProviderRegistry registry;
94 protected DeviceProviderService providerService;
95 protected TestProvider provider;
96 protected TestListener listener = new TestListener();
97
98 @Before
99 public void setUp() {
tom41a2c5f2014-09-19 09:20:35 -0700100 mgr = new DeviceManager();
tome5ec3fd2014-09-04 15:18:06 -0700101 service = mgr;
102 admin = mgr;
103 registry = mgr;
tom41a2c5f2014-09-19 09:20:35 -0700104 mgr.store = new SimpleDeviceStore();
tome5ec3fd2014-09-04 15:18:06 -0700105 mgr.eventDispatcher = new TestEventDispatcher();
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700106 mgr.mastershipService = new TestMastershipService();
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700107 mgr.clusterService = new TestClusterService();
Yuta HIGUCHI093e83e2014-10-10 22:26:11 -0700108 mgr.deviceClockProviderService = new TestClockProviderService();
tome5ec3fd2014-09-04 15:18:06 -0700109 mgr.activate();
110
111 service.addListener(listener);
112
113 provider = new TestProvider();
114 providerService = registry.register(provider);
115 assertTrue("provider should be registered",
116 registry.getProviders().contains(provider.id()));
117 }
118
119 @After
120 public void tearDown() {
121 registry.unregister(provider);
122 assertFalse("provider should not be registered",
123 registry.getProviders().contains(provider.id()));
124 service.removeListener(listener);
125 mgr.deactivate();
126 }
127
128 private void connectDevice(DeviceId deviceId, String swVersion) {
129 DeviceDescription description =
130 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
alshabib7911a052014-10-16 17:49:37 -0700131 HW, swVersion, SN, CID);
tome5ec3fd2014-09-04 15:18:06 -0700132 providerService.deviceConnected(deviceId, description);
133 assertNotNull("device should be found", service.getDevice(DID1));
134 }
135
136 @Test
137 public void deviceConnected() {
138 assertNull("device should not be found", service.getDevice(DID1));
139 connectDevice(DID1, SW1);
140 validateEvents(DEVICE_ADDED);
141
142 Iterator<Device> it = service.getDevices().iterator();
143 assertNotNull("one device expected", it.next());
144 assertFalse("only one device expected", it.hasNext());
tomad2d2092014-09-06 23:24:20 -0700145 assertEquals("incorrect device count", 1, service.getDeviceCount());
tomff7eb7c2014-09-08 12:49:03 -0700146 assertTrue("device should be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700147 }
148
149 @Test
150 public void deviceDisconnected() {
151 connectDevice(DID1, SW1);
152 connectDevice(DID2, SW1);
153 validateEvents(DEVICE_ADDED, DEVICE_ADDED);
tomff7eb7c2014-09-08 12:49:03 -0700154 assertTrue("device should be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700155
156 // Disconnect
157 providerService.deviceDisconnected(DID1);
158 assertNotNull("device should not be found", service.getDevice(DID1));
tomff7eb7c2014-09-08 12:49:03 -0700159 assertFalse("device should not be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700160 validateEvents(DEVICE_AVAILABILITY_CHANGED);
161
162 // Reconnect
163 connectDevice(DID1, SW1);
164 validateEvents(DEVICE_AVAILABILITY_CHANGED);
tomad2d2092014-09-06 23:24:20 -0700165
166 assertEquals("incorrect device count", 2, service.getDeviceCount());
tome5ec3fd2014-09-04 15:18:06 -0700167 }
168
169 @Test
170 public void deviceUpdated() {
171 connectDevice(DID1, SW1);
172 validateEvents(DEVICE_ADDED);
173
174 connectDevice(DID1, SW2);
175 validateEvents(DEVICE_UPDATED);
176 }
177
178 @Test
179 public void getRole() {
180 connectDevice(DID1, SW1);
tom80c0e5e2014-09-08 18:08:58 -0700181 assertEquals("incorrect role", MastershipRole.MASTER, service.getRole(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700182 }
183
tomb41d1ac2014-09-24 01:51:24 -0700184 @Ignore("disabled until we settle the device-mastership wiring")
tome5ec3fd2014-09-04 15:18:06 -0700185 @Test
tom5f35f7c2014-09-08 18:38:19 -0700186 public void setRole() throws InterruptedException {
tome5ec3fd2014-09-04 15:18:06 -0700187 connectDevice(DID1, SW1);
tome5ec3fd2014-09-04 15:18:06 -0700188 validateEvents(DEVICE_ADDED, DEVICE_MASTERSHIP_CHANGED);
tom80c0e5e2014-09-08 18:08:58 -0700189 assertEquals("incorrect role", MastershipRole.STANDBY, service.getRole(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700190 assertEquals("incorrect device", DID1, provider.deviceReceived.id());
tom80c0e5e2014-09-08 18:08:58 -0700191 assertEquals("incorrect role", MastershipRole.STANDBY, provider.roleReceived);
tome5ec3fd2014-09-04 15:18:06 -0700192 }
193
tom24c55cd2014-09-06 10:47:25 -0700194 @Test
195 public void updatePorts() {
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 pds.add(new DefaultPortDescription(P3, true));
201 providerService.updatePorts(DID1, pds);
202 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED);
203 pds.clear();
tome5ec3fd2014-09-04 15:18:06 -0700204
tom24c55cd2014-09-06 10:47:25 -0700205 pds.add(new DefaultPortDescription(P1, false));
206 pds.add(new DefaultPortDescription(P3, true));
207 providerService.updatePorts(DID1, pds);
208 validateEvents(PORT_UPDATED, PORT_REMOVED);
209 }
210
211 @Test
212 public void updatePortStatus() {
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
220 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
221 validateEvents(PORT_UPDATED);
222 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
223 assertTrue("no events expected", listener.events.isEmpty());
224 }
225
226 @Test
227 public void getPorts() {
228 connectDevice(DID1, SW1);
229 List<PortDescription> pds = new ArrayList<>();
230 pds.add(new DefaultPortDescription(P1, true));
231 pds.add(new DefaultPortDescription(P2, true));
232 providerService.updatePorts(DID1, pds);
233 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
234 assertEquals("wrong port count", 2, service.getPorts(DID1).size());
235
236 Port port = service.getPort(DID1, P1);
237 assertEquals("incorrect port", P1, service.getPort(DID1, P1).number());
238 assertEquals("incorrect state", true, service.getPort(DID1, P1).isEnabled());
239 }
240
241 @Test
242 public void removeDevice() {
243 connectDevice(DID1, SW1);
244 connectDevice(DID2, SW2);
tomad2d2092014-09-06 23:24:20 -0700245 assertEquals("incorrect device count", 2, service.getDeviceCount());
tom24c55cd2014-09-06 10:47:25 -0700246 admin.removeDevice(DID1);
247 assertNull("device should not be found", service.getDevice(DID1));
248 assertNotNull("device should be found", service.getDevice(DID2));
tomad2d2092014-09-06 23:24:20 -0700249 assertEquals("incorrect device count", 1, service.getDeviceCount());
250
tom24c55cd2014-09-06 10:47:25 -0700251 }
tome5ec3fd2014-09-04 15:18:06 -0700252
253 protected void validateEvents(Enum... types) {
254 int i = 0;
255 assertEquals("wrong events received", types.length, listener.events.size());
256 for (Event event : listener.events) {
257 assertEquals("incorrect event type", types[i], event.type());
258 i++;
259 }
260 listener.events.clear();
261 }
262
263
264 private class TestProvider extends AbstractProvider implements DeviceProvider {
265 private Device deviceReceived;
266 private MastershipRole roleReceived;
267
268 public TestProvider() {
269 super(PID);
270 }
271
272 @Override
273 public void triggerProbe(Device device) {
274 }
275
276 @Override
277 public void roleChanged(Device device, MastershipRole newRole) {
278 deviceReceived = device;
279 roleReceived = newRole;
280 }
281 }
282
283 private static class TestListener implements DeviceListener {
284 final List<DeviceEvent> events = new ArrayList<>();
285
286 @Override
287 public void event(DeviceEvent event) {
288 events.add(event);
289 }
290 }
291
Ayaka Koshibec4047702014-10-07 14:43:52 -0700292 private static class TestMastershipService
293 extends MastershipServiceAdapter {
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700294 @Override
tomb41d1ac2014-09-24 01:51:24 -0700295 public MastershipRole getLocalRole(DeviceId deviceId) {
296 return MastershipRole.MASTER;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700297 }
298
299 @Override
300 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
301 return Sets.newHashSet(DID1, DID2);
302 }
303
304 @Override
305 public MastershipRole requestRoleFor(DeviceId deviceId) {
306 return MastershipRole.MASTER;
307 }
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700308
309 @Override
310 public MastershipTermService requestTermService() {
311 return new MastershipTermService() {
312 @Override
313 public MastershipTerm getMastershipTerm(DeviceId deviceId) {
314 // FIXME: just returning something not null
315 return MastershipTerm.of(NID_LOCAL, 1);
316 }
317 };
318 }
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700319 }
320
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700321 // code clone
322 private final class TestClusterService implements ClusterService {
323
324 ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST);
325
326 @Override
327 public ControllerNode getLocalNode() {
328 return local;
329 }
330
331 @Override
332 public Set<ControllerNode> getNodes() {
333 return null;
334 }
335
336 @Override
337 public ControllerNode getNode(NodeId nodeId) {
338 return null;
339 }
340
341 @Override
342 public State getState(NodeId nodeId) {
343 return null;
344 }
345
346 @Override
347 public void addListener(ClusterEventListener listener) {
348 }
349
350 @Override
351 public void removeListener(ClusterEventListener listener) {
352 }
353 }
354
355 private final class TestClockProviderService implements
Yuta HIGUCHI093e83e2014-10-10 22:26:11 -0700356 DeviceClockProviderService {
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700357
358 @Override
359 public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) {
360 // TODO Auto-generated method stub
361 }
362 }
tome5ec3fd2014-09-04 15:18:06 -0700363}