blob: ca8aa34927679149e98445f9c492832fe203677a [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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.device.impl;
tome5ec3fd2014-09-04 15:18:06 -070017
Ray Milkeycc53abd2015-02-19 12:31:33 -080018import java.util.ArrayList;
19import java.util.Iterator;
20import java.util.List;
21import java.util.Set;
Ayaka Koshibec4047702014-10-07 14:43:52 -070022
tome5ec3fd2014-09-04 15:18:06 -070023import org.junit.After;
24import org.junit.Before;
25import org.junit.Test;
Ray Milkeycc53abd2015-02-19 12:31:33 -080026import org.onlab.packet.ChassisId;
27import org.onlab.packet.IpAddress;
28import org.onosproject.cluster.ClusterServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080029import org.onosproject.cluster.ControllerNode;
30import org.onosproject.cluster.DefaultControllerNode;
31import org.onosproject.cluster.NodeId;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.event.Event;
33import org.onosproject.event.impl.TestEventDispatcher;
34import org.onosproject.mastership.MastershipServiceAdapter;
35import org.onosproject.mastership.MastershipTerm;
36import org.onosproject.mastership.MastershipTermService;
37import org.onosproject.net.Device;
38import org.onosproject.net.DeviceId;
39import org.onosproject.net.MastershipRole;
40import org.onosproject.net.Port;
41import org.onosproject.net.PortNumber;
42import org.onosproject.net.device.DefaultDeviceDescription;
43import org.onosproject.net.device.DefaultPortDescription;
44import org.onosproject.net.device.DeviceAdminService;
45import org.onosproject.net.device.DeviceClockProviderService;
46import org.onosproject.net.device.DeviceDescription;
47import org.onosproject.net.device.DeviceEvent;
48import org.onosproject.net.device.DeviceListener;
49import org.onosproject.net.device.DeviceProvider;
50import org.onosproject.net.device.DeviceProviderRegistry;
51import org.onosproject.net.device.DeviceProviderService;
52import org.onosproject.net.device.DeviceService;
53import org.onosproject.net.device.PortDescription;
54import org.onosproject.net.provider.AbstractProvider;
55import org.onosproject.net.provider.ProviderId;
56import org.onosproject.store.trivial.impl.SimpleDeviceStore;
tome5ec3fd2014-09-04 15:18:06 -070057
Ray Milkeycc53abd2015-02-19 12:31:33 -080058import com.google.common.collect.Sets;
tome5ec3fd2014-09-04 15:18:06 -070059
Ray Milkeycc53abd2015-02-19 12:31:33 -080060import static org.junit.Assert.assertEquals;
61import static org.junit.Assert.assertFalse;
62import static org.junit.Assert.assertNotNull;
63import static org.junit.Assert.assertNull;
64import static org.junit.Assert.assertTrue;
Brian O'Connorabafb502014-12-02 22:26:20 -080065import static org.onosproject.net.Device.Type.SWITCH;
66import static org.onosproject.net.DeviceId.deviceId;
Ray Milkeycc53abd2015-02-19 12:31:33 -080067import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
68import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
69import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_UPDATED;
70import static org.onosproject.net.device.DeviceEvent.Type.PORT_ADDED;
71import static org.onosproject.net.device.DeviceEvent.Type.PORT_REMOVED;
72import static org.onosproject.net.device.DeviceEvent.Type.PORT_UPDATED;
tome5ec3fd2014-09-04 15:18:06 -070073
74/**
75 * Test codifying the device service & device provider service contracts.
76 */
tom41a2c5f2014-09-19 09:20:35 -070077public class DeviceManagerTest {
tome5ec3fd2014-09-04 15:18:06 -070078
tom7e02cda2014-09-18 12:05:46 -070079 private static final ProviderId PID = new ProviderId("of", "foo");
tome5ec3fd2014-09-04 15:18:06 -070080 private static final DeviceId DID1 = deviceId("of:foo");
81 private static final DeviceId DID2 = deviceId("of:bar");
82 private static final String MFR = "whitebox";
83 private static final String HW = "1.1.x";
84 private static final String SW1 = "3.8.1";
85 private static final String SW2 = "3.9.5";
86 private static final String SN = "43311-12345";
alshabib7911a052014-10-16 17:49:37 -070087 private static final ChassisId CID = new ChassisId();
tome5ec3fd2014-09-04 15:18:06 -070088
tom24c55cd2014-09-06 10:47:25 -070089 private static final PortNumber P1 = PortNumber.portNumber(1);
90 private static final PortNumber P2 = PortNumber.portNumber(2);
91 private static final PortNumber P3 = PortNumber.portNumber(3);
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070092 private static final NodeId NID_LOCAL = new NodeId("local");
Pavlin Radoslavov444b5192014-10-28 10:45:19 -070093 private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
tom24c55cd2014-09-06 10:47:25 -070094
tom41a2c5f2014-09-19 09:20:35 -070095 private DeviceManager mgr;
tome5ec3fd2014-09-04 15:18:06 -070096
97 protected DeviceService service;
98 protected DeviceAdminService admin;
99 protected DeviceProviderRegistry registry;
100 protected DeviceProviderService providerService;
101 protected TestProvider provider;
102 protected TestListener listener = new TestListener();
103
104 @Before
105 public void setUp() {
tom41a2c5f2014-09-19 09:20:35 -0700106 mgr = new DeviceManager();
tome5ec3fd2014-09-04 15:18:06 -0700107 service = mgr;
108 admin = mgr;
109 registry = mgr;
tom41a2c5f2014-09-19 09:20:35 -0700110 mgr.store = new SimpleDeviceStore();
tome5ec3fd2014-09-04 15:18:06 -0700111 mgr.eventDispatcher = new TestEventDispatcher();
Yuta HIGUCHIbcac4992014-11-22 19:27:57 -0800112 TestMastershipManager mastershipManager = new TestMastershipManager();
113 mgr.mastershipService = mastershipManager;
114 mgr.termService = mastershipManager;
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700115 mgr.clusterService = new TestClusterService();
Yuta HIGUCHI093e83e2014-10-10 22:26:11 -0700116 mgr.deviceClockProviderService = new TestClockProviderService();
tome5ec3fd2014-09-04 15:18:06 -0700117 mgr.activate();
118
119 service.addListener(listener);
120
121 provider = new TestProvider();
122 providerService = registry.register(provider);
123 assertTrue("provider should be registered",
124 registry.getProviders().contains(provider.id()));
125 }
126
127 @After
128 public void tearDown() {
129 registry.unregister(provider);
130 assertFalse("provider should not be registered",
131 registry.getProviders().contains(provider.id()));
132 service.removeListener(listener);
133 mgr.deactivate();
134 }
135
136 private void connectDevice(DeviceId deviceId, String swVersion) {
137 DeviceDescription description =
138 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
alshabib7911a052014-10-16 17:49:37 -0700139 HW, swVersion, SN, CID);
tome5ec3fd2014-09-04 15:18:06 -0700140 providerService.deviceConnected(deviceId, description);
141 assertNotNull("device should be found", service.getDevice(DID1));
142 }
143
144 @Test
145 public void deviceConnected() {
146 assertNull("device should not be found", service.getDevice(DID1));
147 connectDevice(DID1, SW1);
148 validateEvents(DEVICE_ADDED);
149
150 Iterator<Device> it = service.getDevices().iterator();
151 assertNotNull("one device expected", it.next());
152 assertFalse("only one device expected", it.hasNext());
tomad2d2092014-09-06 23:24:20 -0700153 assertEquals("incorrect device count", 1, service.getDeviceCount());
tomff7eb7c2014-09-08 12:49:03 -0700154 assertTrue("device should be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700155 }
156
157 @Test
158 public void deviceDisconnected() {
159 connectDevice(DID1, SW1);
160 connectDevice(DID2, SW1);
161 validateEvents(DEVICE_ADDED, DEVICE_ADDED);
tomff7eb7c2014-09-08 12:49:03 -0700162 assertTrue("device should be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700163
164 // Disconnect
165 providerService.deviceDisconnected(DID1);
166 assertNotNull("device should not be found", service.getDevice(DID1));
tomff7eb7c2014-09-08 12:49:03 -0700167 assertFalse("device should not be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700168 validateEvents(DEVICE_AVAILABILITY_CHANGED);
169
170 // Reconnect
171 connectDevice(DID1, SW1);
172 validateEvents(DEVICE_AVAILABILITY_CHANGED);
tomad2d2092014-09-06 23:24:20 -0700173
174 assertEquals("incorrect device count", 2, service.getDeviceCount());
tome5ec3fd2014-09-04 15:18:06 -0700175 }
176
177 @Test
178 public void deviceUpdated() {
179 connectDevice(DID1, SW1);
180 validateEvents(DEVICE_ADDED);
181
182 connectDevice(DID1, SW2);
183 validateEvents(DEVICE_UPDATED);
184 }
185
186 @Test
187 public void getRole() {
188 connectDevice(DID1, SW1);
tom80c0e5e2014-09-08 18:08:58 -0700189 assertEquals("incorrect role", MastershipRole.MASTER, service.getRole(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700190 }
191
tom24c55cd2014-09-06 10:47:25 -0700192 @Test
193 public void updatePorts() {
194 connectDevice(DID1, SW1);
195 List<PortDescription> pds = new ArrayList<>();
196 pds.add(new DefaultPortDescription(P1, true));
197 pds.add(new DefaultPortDescription(P2, true));
198 pds.add(new DefaultPortDescription(P3, true));
199 providerService.updatePorts(DID1, pds);
200 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED);
201 pds.clear();
tome5ec3fd2014-09-04 15:18:06 -0700202
tom24c55cd2014-09-06 10:47:25 -0700203 pds.add(new DefaultPortDescription(P1, false));
204 pds.add(new DefaultPortDescription(P3, true));
205 providerService.updatePorts(DID1, pds);
206 validateEvents(PORT_UPDATED, PORT_REMOVED);
207 }
208
209 @Test
210 public void updatePortStatus() {
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
218 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
219 validateEvents(PORT_UPDATED);
220 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
221 assertTrue("no events expected", listener.events.isEmpty());
222 }
223
224 @Test
225 public void getPorts() {
226 connectDevice(DID1, SW1);
227 List<PortDescription> pds = new ArrayList<>();
228 pds.add(new DefaultPortDescription(P1, true));
229 pds.add(new DefaultPortDescription(P2, true));
230 providerService.updatePorts(DID1, pds);
231 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
232 assertEquals("wrong port count", 2, service.getPorts(DID1).size());
233
234 Port port = service.getPort(DID1, P1);
235 assertEquals("incorrect port", P1, service.getPort(DID1, P1).number());
236 assertEquals("incorrect state", true, service.getPort(DID1, P1).isEnabled());
237 }
238
239 @Test
240 public void removeDevice() {
241 connectDevice(DID1, SW1);
242 connectDevice(DID2, SW2);
tomad2d2092014-09-06 23:24:20 -0700243 assertEquals("incorrect device count", 2, service.getDeviceCount());
tom24c55cd2014-09-06 10:47:25 -0700244 admin.removeDevice(DID1);
245 assertNull("device should not be found", service.getDevice(DID1));
246 assertNotNull("device should be found", service.getDevice(DID2));
tomad2d2092014-09-06 23:24:20 -0700247 assertEquals("incorrect device count", 1, service.getDeviceCount());
248
tom24c55cd2014-09-06 10:47:25 -0700249 }
tome5ec3fd2014-09-04 15:18:06 -0700250
251 protected void validateEvents(Enum... types) {
252 int i = 0;
253 assertEquals("wrong events received", types.length, listener.events.size());
254 for (Event event : listener.events) {
255 assertEquals("incorrect event type", types[i], event.type());
256 i++;
257 }
258 listener.events.clear();
259 }
260
261
262 private class TestProvider extends AbstractProvider implements DeviceProvider {
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700263 private DeviceId deviceReceived;
tome5ec3fd2014-09-04 15:18:06 -0700264 private MastershipRole roleReceived;
265
266 public TestProvider() {
267 super(PID);
268 }
269
270 @Override
Ayaka Koshibe78bcbc12014-11-19 14:28:58 -0800271 public void triggerProbe(DeviceId deviceId) {
tome5ec3fd2014-09-04 15:18:06 -0700272 }
273
274 @Override
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700275 public void roleChanged(DeviceId device, MastershipRole newRole) {
tome5ec3fd2014-09-04 15:18:06 -0700276 deviceReceived = device;
277 roleReceived = newRole;
278 }
Ayaka Koshibee60d4522014-10-28 15:07:00 -0700279
280 @Override
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700281 public boolean isReachable(DeviceId device) {
Ayaka Koshibee60d4522014-10-28 15:07:00 -0700282 return false;
283 }
tome5ec3fd2014-09-04 15:18:06 -0700284 }
285
286 private static class TestListener implements DeviceListener {
287 final List<DeviceEvent> events = new ArrayList<>();
288
289 @Override
290 public void event(DeviceEvent event) {
291 events.add(event);
292 }
293 }
294
Yuta HIGUCHIbcac4992014-11-22 19:27:57 -0800295 private static class TestMastershipManager
296 extends MastershipServiceAdapter implements MastershipTermService {
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700297 @Override
tomb41d1ac2014-09-24 01:51:24 -0700298 public MastershipRole getLocalRole(DeviceId deviceId) {
299 return MastershipRole.MASTER;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700300 }
301
302 @Override
303 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
304 return Sets.newHashSet(DID1, DID2);
305 }
306
307 @Override
308 public MastershipRole requestRoleFor(DeviceId deviceId) {
309 return MastershipRole.MASTER;
310 }
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700311
312 @Override
Yuta HIGUCHIbcac4992014-11-22 19:27:57 -0800313 public MastershipTerm getMastershipTerm(DeviceId deviceId) {
314 // FIXME: just returning something not null
315 return MastershipTerm.of(NID_LOCAL, 1);
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700316 }
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700317 }
318
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700319 // code clone
Ray Milkeycc53abd2015-02-19 12:31:33 -0800320 private final class TestClusterService extends ClusterServiceAdapter {
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700321
322 ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST);
323
324 @Override
325 public ControllerNode getLocalNode() {
326 return local;
327 }
328
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700329 }
330
331 private final class TestClockProviderService implements
Yuta HIGUCHI093e83e2014-10-10 22:26:11 -0700332 DeviceClockProviderService {
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700333
Yuta HIGUCHI13c0b872014-10-30 18:09:22 -0700334 private Set<DeviceId> registerdBefore = Sets.newConcurrentHashSet();
335
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700336 @Override
337 public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) {
Yuta HIGUCHI13c0b872014-10-30 18:09:22 -0700338 registerdBefore.add(deviceId);
339 }
340
341 @Override
342 public boolean isTimestampAvailable(DeviceId deviceId) {
343 return registerdBefore.contains(deviceId);
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700344 }
345 }
tome5ec3fd2014-09-04 15:18:06 -0700346}