blob: 3e1e4d1e8fae9d3b0acfb786dcd20bfca59efe05 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2014-present Open Networking Foundation
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
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
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070018import com.google.common.collect.Sets;
tome5ec3fd2014-09-04 15:18:06 -070019import org.junit.After;
20import org.junit.Before;
21import org.junit.Test;
Ray Milkeycc53abd2015-02-19 12:31:33 -080022import org.onlab.packet.ChassisId;
23import org.onlab.packet.IpAddress;
24import org.onosproject.cluster.ClusterServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080025import org.onosproject.cluster.ControllerNode;
26import org.onosproject.cluster.DefaultControllerNode;
27import org.onosproject.cluster.NodeId;
Thomas Vachuska36002e62015-05-19 16:12:29 -070028import org.onosproject.common.event.impl.TestEventDispatcher;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070029import org.onosproject.event.Event;
Ray Milkeya4122362015-08-18 15:19:08 -070030import org.onosproject.net.config.NetworkConfigServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.mastership.MastershipServiceAdapter;
32import org.onosproject.mastership.MastershipTerm;
33import org.onosproject.mastership.MastershipTermService;
34import org.onosproject.net.Device;
35import org.onosproject.net.DeviceId;
36import org.onosproject.net.MastershipRole;
37import org.onosproject.net.Port;
38import org.onosproject.net.PortNumber;
39import org.onosproject.net.device.DefaultDeviceDescription;
40import org.onosproject.net.device.DefaultPortDescription;
41import org.onosproject.net.device.DeviceAdminService;
Brian O'Connorabafb502014-12-02 22:26:20 -080042import org.onosproject.net.device.DeviceDescription;
43import org.onosproject.net.device.DeviceEvent;
44import org.onosproject.net.device.DeviceListener;
45import org.onosproject.net.device.DeviceProvider;
46import org.onosproject.net.device.DeviceProviderRegistry;
47import org.onosproject.net.device.DeviceProviderService;
48import org.onosproject.net.device.DeviceService;
49import org.onosproject.net.device.PortDescription;
50import org.onosproject.net.provider.AbstractProvider;
51import org.onosproject.net.provider.ProviderId;
Jonghwan Hyun6ecf56d2017-08-01 16:07:44 -070052import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter;
Thomas Vachuskac97aa612015-06-23 16:00:18 -070053import org.onosproject.store.trivial.SimpleDeviceStore;
tome5ec3fd2014-09-04 15:18:06 -070054
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070055import java.util.ArrayList;
56import java.util.Iterator;
57import java.util.List;
58import java.util.Set;
59import java.util.concurrent.CompletableFuture;
tome5ec3fd2014-09-04 15:18:06 -070060
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070061import static org.junit.Assert.*;
Brian O'Connorabafb502014-12-02 22:26:20 -080062import static org.onosproject.net.Device.Type.SWITCH;
63import static org.onosproject.net.DeviceId.deviceId;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070064import static org.onosproject.net.NetTestTools.injectEventDispatcher;
65import static org.onosproject.net.device.DeviceEvent.Type.*;
tome5ec3fd2014-09-04 15:18:06 -070066
67/**
68 * Test codifying the device service & device provider service contracts.
69 */
tom41a2c5f2014-09-19 09:20:35 -070070public class DeviceManagerTest {
tome5ec3fd2014-09-04 15:18:06 -070071
tom7e02cda2014-09-18 12:05:46 -070072 private static final ProviderId PID = new ProviderId("of", "foo");
tome5ec3fd2014-09-04 15:18:06 -070073 private static final DeviceId DID1 = deviceId("of:foo");
74 private static final DeviceId DID2 = deviceId("of:bar");
75 private static final String MFR = "whitebox";
76 private static final String HW = "1.1.x";
77 private static final String SW1 = "3.8.1";
78 private static final String SW2 = "3.9.5";
79 private static final String SN = "43311-12345";
alshabib7911a052014-10-16 17:49:37 -070080 private static final ChassisId CID = new ChassisId();
tome5ec3fd2014-09-04 15:18:06 -070081
tom24c55cd2014-09-06 10:47:25 -070082 private static final PortNumber P1 = PortNumber.portNumber(1);
83 private static final PortNumber P2 = PortNumber.portNumber(2);
84 private static final PortNumber P3 = PortNumber.portNumber(3);
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070085 private static final NodeId NID_LOCAL = new NodeId("local");
Pavlin Radoslavov444b5192014-10-28 10:45:19 -070086 private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
tom24c55cd2014-09-06 10:47:25 -070087
tom41a2c5f2014-09-19 09:20:35 -070088 private DeviceManager mgr;
tome5ec3fd2014-09-04 15:18:06 -070089
90 protected DeviceService service;
91 protected DeviceAdminService admin;
92 protected DeviceProviderRegistry registry;
93 protected DeviceProviderService providerService;
94 protected TestProvider provider;
95 protected TestListener listener = new TestListener();
96
97 @Before
98 public void setUp() {
tom41a2c5f2014-09-19 09:20:35 -070099 mgr = new DeviceManager();
tome5ec3fd2014-09-04 15:18:06 -0700100 service = mgr;
101 admin = mgr;
102 registry = mgr;
tom41a2c5f2014-09-19 09:20:35 -0700103 mgr.store = new SimpleDeviceStore();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700104 injectEventDispatcher(mgr, new TestEventDispatcher());
Yuta HIGUCHIbcac4992014-11-22 19:27:57 -0800105 TestMastershipManager mastershipManager = new TestMastershipManager();
106 mgr.mastershipService = mastershipManager;
107 mgr.termService = mastershipManager;
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700108 mgr.clusterService = new TestClusterService();
Sahil Lele3a0cdd52015-07-21 14:16:31 -0700109 mgr.networkConfigService = new TestNetworkConfigService();
Jonghwan Hyun6ecf56d2017-08-01 16:07:44 -0700110 mgr.communicationService = new TestClusterCommunicationService();
tome5ec3fd2014-09-04 15:18:06 -0700111 mgr.activate();
112
Sahil Lele3a0cdd52015-07-21 14:16:31 -0700113
tome5ec3fd2014-09-04 15:18:06 -0700114 service.addListener(listener);
115
116 provider = new TestProvider();
117 providerService = registry.register(provider);
118 assertTrue("provider should be registered",
119 registry.getProviders().contains(provider.id()));
120 }
121
122 @After
123 public void tearDown() {
124 registry.unregister(provider);
125 assertFalse("provider should not be registered",
126 registry.getProviders().contains(provider.id()));
127 service.removeListener(listener);
128 mgr.deactivate();
129 }
130
131 private void connectDevice(DeviceId deviceId, String swVersion) {
132 DeviceDescription description =
133 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
alshabib7911a052014-10-16 17:49:37 -0700134 HW, swVersion, SN, CID);
tome5ec3fd2014-09-04 15:18:06 -0700135 providerService.deviceConnected(deviceId, description);
136 assertNotNull("device should be found", service.getDevice(DID1));
137 }
138
139 @Test
140 public void deviceConnected() {
141 assertNull("device should not be found", service.getDevice(DID1));
142 connectDevice(DID1, SW1);
143 validateEvents(DEVICE_ADDED);
144
145 Iterator<Device> it = service.getDevices().iterator();
146 assertNotNull("one device expected", it.next());
147 assertFalse("only one device expected", it.hasNext());
tomad2d2092014-09-06 23:24:20 -0700148 assertEquals("incorrect device count", 1, service.getDeviceCount());
mskala32000d32017-07-14 16:27:06 +0200149 assertEquals("incorrect available device count", 1, service.getAvailableDeviceCount());
tomff7eb7c2014-09-08 12:49:03 -0700150 assertTrue("device should be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700151 }
152
153 @Test
154 public void deviceDisconnected() {
155 connectDevice(DID1, SW1);
156 connectDevice(DID2, SW1);
157 validateEvents(DEVICE_ADDED, DEVICE_ADDED);
tomff7eb7c2014-09-08 12:49:03 -0700158 assertTrue("device should be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700159
160 // Disconnect
161 providerService.deviceDisconnected(DID1);
162 assertNotNull("device should not be found", service.getDevice(DID1));
tomff7eb7c2014-09-08 12:49:03 -0700163 assertFalse("device should not be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700164 validateEvents(DEVICE_AVAILABILITY_CHANGED);
165
166 // Reconnect
167 connectDevice(DID1, SW1);
168 validateEvents(DEVICE_AVAILABILITY_CHANGED);
tomad2d2092014-09-06 23:24:20 -0700169
170 assertEquals("incorrect device count", 2, service.getDeviceCount());
mskala32000d32017-07-14 16:27:06 +0200171 assertEquals("incorrect available device count", 2, service.getAvailableDeviceCount());
tome5ec3fd2014-09-04 15:18:06 -0700172 }
173
174 @Test
175 public void deviceUpdated() {
176 connectDevice(DID1, SW1);
177 validateEvents(DEVICE_ADDED);
178
179 connectDevice(DID1, SW2);
180 validateEvents(DEVICE_UPDATED);
181 }
182
183 @Test
184 public void getRole() {
185 connectDevice(DID1, SW1);
tom80c0e5e2014-09-08 18:08:58 -0700186 assertEquals("incorrect role", MastershipRole.MASTER, service.getRole(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700187 }
188
tom24c55cd2014-09-06 10:47:25 -0700189 @Test
190 public void updatePorts() {
191 connectDevice(DID1, SW1);
192 List<PortDescription> pds = new ArrayList<>();
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800193 pds.add(DefaultPortDescription.builder().withPortNumber(P1).isEnabled(true).build());
194 pds.add(DefaultPortDescription.builder().withPortNumber(P2).isEnabled(true).build());
195 pds.add(DefaultPortDescription.builder().withPortNumber(P3).isEnabled(true).build());
tom24c55cd2014-09-06 10:47:25 -0700196 providerService.updatePorts(DID1, pds);
197 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED);
198 pds.clear();
tome5ec3fd2014-09-04 15:18:06 -0700199
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800200 pds.add(DefaultPortDescription.builder().withPortNumber(P1).isEnabled(false).build());
201 pds.add(DefaultPortDescription.builder().withPortNumber(P3).isEnabled(true).build());
tom24c55cd2014-09-06 10:47:25 -0700202 providerService.updatePorts(DID1, pds);
203 validateEvents(PORT_UPDATED, PORT_REMOVED);
204 }
205
206 @Test
207 public void updatePortStatus() {
208 connectDevice(DID1, SW1);
209 List<PortDescription> pds = new ArrayList<>();
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800210 pds.add(DefaultPortDescription.builder().withPortNumber(P1).isEnabled(true).build());
211 pds.add(DefaultPortDescription.builder().withPortNumber(P2).isEnabled(true).build());
tom24c55cd2014-09-06 10:47:25 -0700212 providerService.updatePorts(DID1, pds);
213 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
214
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800215 providerService.portStatusChanged(DID1, DefaultPortDescription.builder()
216 .withPortNumber(P1).isEnabled(false).build());
tom24c55cd2014-09-06 10:47:25 -0700217 validateEvents(PORT_UPDATED);
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800218 providerService.portStatusChanged(DID1, DefaultPortDescription.builder()
219 .withPortNumber(P1).isEnabled(false).build());
tom24c55cd2014-09-06 10:47:25 -0700220 assertTrue("no events expected", listener.events.isEmpty());
221 }
222
223 @Test
224 public void getPorts() {
225 connectDevice(DID1, SW1);
226 List<PortDescription> pds = new ArrayList<>();
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800227 pds.add(DefaultPortDescription.builder().withPortNumber(P1).isEnabled(true).build());
228 pds.add(DefaultPortDescription.builder().withPortNumber(P2).isEnabled(true).build());
tom24c55cd2014-09-06 10:47:25 -0700229 providerService.updatePorts(DID1, pds);
230 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
231 assertEquals("wrong port count", 2, service.getPorts(DID1).size());
232
233 Port port = service.getPort(DID1, P1);
mskala32000d32017-07-14 16:27:06 +0200234 assertEquals("incorrect port", P1, port.number());
235 assertEquals("incorrect state", true, port.isEnabled());
tom24c55cd2014-09-06 10:47:25 -0700236 }
237
238 @Test
239 public void removeDevice() {
240 connectDevice(DID1, SW1);
241 connectDevice(DID2, SW2);
tomad2d2092014-09-06 23:24:20 -0700242 assertEquals("incorrect device count", 2, service.getDeviceCount());
mskala32000d32017-07-14 16:27:06 +0200243 assertEquals("incorrect available device count", 2, service.getAvailableDeviceCount());
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());
mskala32000d32017-07-14 16:27:06 +0200248 assertEquals("incorrect available device count", 1, service.getAvailableDeviceCount());
Thomas Vachuska811ea2b2020-02-11 10:20:10 -0800249 }
tomad2d2092014-09-06 23:24:20 -0700250
Thomas Vachuska811ea2b2020-02-11 10:20:10 -0800251 @Test
252 public void removeDevicePorts() {
253 connectDevice(DID1, SW1);
254 List<PortDescription> pds = new ArrayList<>();
255 pds.add(DefaultPortDescription.builder().withPortNumber(P1).isEnabled(true).build());
256 pds.add(DefaultPortDescription.builder().withPortNumber(P2).isEnabled(true).build());
257 pds.add(DefaultPortDescription.builder().withPortNumber(P3).isEnabled(true).build());
258 providerService.updatePorts(DID1, pds);
259 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED);
260
261 // Try removing ports while device is available/connected; it should be a no-op.
262 admin.removeDevicePorts(DID1);
263 assertEquals("wrong port count", 3, service.getPorts(DID1).size());
264
265 // Disconnect device
266 providerService.deviceDisconnected(DID1);
267 assertFalse("device should not be available", service.isAvailable(DID1));
268 validateEvents(DEVICE_AVAILABILITY_CHANGED);
269
270 // Now remove ports for real
271 admin.removeDevicePorts(DID1);
272 validateEvents(PORT_REMOVED, PORT_REMOVED, PORT_REMOVED);
273 assertEquals("wrong port count", 0, service.getPorts(DID1).size());
tom24c55cd2014-09-06 10:47:25 -0700274 }
tome5ec3fd2014-09-04 15:18:06 -0700275
276 protected void validateEvents(Enum... types) {
277 int i = 0;
278 assertEquals("wrong events received", types.length, listener.events.size());
279 for (Event event : listener.events) {
280 assertEquals("incorrect event type", types[i], event.type());
281 i++;
282 }
283 listener.events.clear();
284 }
285
286
287 private class TestProvider extends AbstractProvider implements DeviceProvider {
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700288 private DeviceId deviceReceived;
tome5ec3fd2014-09-04 15:18:06 -0700289 private MastershipRole roleReceived;
290
291 public TestProvider() {
292 super(PID);
293 }
294
295 @Override
Ayaka Koshibe78bcbc12014-11-19 14:28:58 -0800296 public void triggerProbe(DeviceId deviceId) {
tome5ec3fd2014-09-04 15:18:06 -0700297 }
298
299 @Override
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700300 public void roleChanged(DeviceId device, MastershipRole newRole) {
tome5ec3fd2014-09-04 15:18:06 -0700301 deviceReceived = device;
302 roleReceived = newRole;
303 }
Ayaka Koshibee60d4522014-10-28 15:07:00 -0700304
305 @Override
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700306 public boolean isReachable(DeviceId device) {
Ayaka Koshibee60d4522014-10-28 15:07:00 -0700307 return false;
308 }
Saurav Dasa2d37502016-03-25 17:50:40 -0700309
310 @Override
311 public void changePortState(DeviceId deviceId, PortNumber portNumber,
312 boolean enable) {
313 }
tome5ec3fd2014-09-04 15:18:06 -0700314 }
315
316 private static class TestListener implements DeviceListener {
317 final List<DeviceEvent> events = new ArrayList<>();
318
319 @Override
320 public void event(DeviceEvent event) {
321 events.add(event);
322 }
323 }
324
Yuta HIGUCHIbcac4992014-11-22 19:27:57 -0800325 private static class TestMastershipManager
326 extends MastershipServiceAdapter implements MastershipTermService {
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700327 @Override
tomb41d1ac2014-09-24 01:51:24 -0700328 public MastershipRole getLocalRole(DeviceId deviceId) {
329 return MastershipRole.MASTER;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700330 }
331
332 @Override
333 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
334 return Sets.newHashSet(DID1, DID2);
335 }
336
337 @Override
Madan Jampanide003d92015-05-11 17:14:20 -0700338 public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
339 return CompletableFuture.completedFuture(MastershipRole.MASTER);
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700340 }
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700341
342 @Override
Madan Jampanic6e574f2015-05-29 13:41:52 -0700343 public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
344 return CompletableFuture.completedFuture(null);
345 }
346
347 @Override
Yuta HIGUCHIbcac4992014-11-22 19:27:57 -0800348 public MastershipTerm getMastershipTerm(DeviceId deviceId) {
349 // FIXME: just returning something not null
350 return MastershipTerm.of(NID_LOCAL, 1);
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700351 }
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700352 }
353
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700354 // code clone
Ray Milkeycc53abd2015-02-19 12:31:33 -0800355 private final class TestClusterService extends ClusterServiceAdapter {
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700356
357 ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST);
358
359 @Override
360 public ControllerNode getLocalNode() {
361 return local;
362 }
363
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700364 }
365
Sahil Lele3a0cdd52015-07-21 14:16:31 -0700366 private class TestNetworkConfigService extends NetworkConfigServiceAdapter {
367 }
Jonghwan Hyun6ecf56d2017-08-01 16:07:44 -0700368
369 private class TestClusterCommunicationService extends ClusterCommunicationServiceAdapter {
370 }
tome5ec3fd2014-09-04 15:18:06 -0700371}