blob: 7597e7c5a4fa8fcc3a832366418d83f572d6e13a [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
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
Ray Milkeycc53abd2015-02-19 12:31:33 -080018import java.util.ArrayList;
19import java.util.Iterator;
20import java.util.List;
21import java.util.Set;
Madan Jampanide003d92015-05-11 17:14:20 -070022import java.util.concurrent.CompletableFuture;
Ayaka Koshibec4047702014-10-07 14:43:52 -070023
tome5ec3fd2014-09-04 15:18:06 -070024import org.junit.After;
25import org.junit.Before;
26import org.junit.Test;
Ray Milkeycc53abd2015-02-19 12:31:33 -080027import org.onlab.packet.ChassisId;
28import org.onlab.packet.IpAddress;
29import org.onosproject.cluster.ClusterServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.cluster.ControllerNode;
31import org.onosproject.cluster.DefaultControllerNode;
32import org.onosproject.cluster.NodeId;
Brian O'Connorabafb502014-12-02 22:26:20 -080033import org.onosproject.event.Event;
Thomas Vachuska36002e62015-05-19 16:12:29 -070034import org.onosproject.common.event.impl.TestEventDispatcher;
Sahil Lele3a0cdd52015-07-21 14:16:31 -070035import org.onosproject.incubator.net.config.NetworkConfigServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080036import org.onosproject.mastership.MastershipServiceAdapter;
37import org.onosproject.mastership.MastershipTerm;
38import org.onosproject.mastership.MastershipTermService;
39import org.onosproject.net.Device;
40import org.onosproject.net.DeviceId;
41import org.onosproject.net.MastershipRole;
42import org.onosproject.net.Port;
43import org.onosproject.net.PortNumber;
44import org.onosproject.net.device.DefaultDeviceDescription;
45import org.onosproject.net.device.DefaultPortDescription;
46import org.onosproject.net.device.DeviceAdminService;
47import org.onosproject.net.device.DeviceClockProviderService;
48import org.onosproject.net.device.DeviceDescription;
49import org.onosproject.net.device.DeviceEvent;
50import org.onosproject.net.device.DeviceListener;
51import org.onosproject.net.device.DeviceProvider;
52import org.onosproject.net.device.DeviceProviderRegistry;
53import org.onosproject.net.device.DeviceProviderService;
54import org.onosproject.net.device.DeviceService;
55import org.onosproject.net.device.PortDescription;
56import org.onosproject.net.provider.AbstractProvider;
57import org.onosproject.net.provider.ProviderId;
Thomas Vachuskac97aa612015-06-23 16:00:18 -070058import org.onosproject.store.trivial.SimpleDeviceStore;
tome5ec3fd2014-09-04 15:18:06 -070059
Ray Milkeycc53abd2015-02-19 12:31:33 -080060import com.google.common.collect.Sets;
tome5ec3fd2014-09-04 15:18:06 -070061
Ray Milkeycc53abd2015-02-19 12:31:33 -080062import static org.junit.Assert.assertEquals;
63import static org.junit.Assert.assertFalse;
64import static org.junit.Assert.assertNotNull;
65import static org.junit.Assert.assertNull;
66import static org.junit.Assert.assertTrue;
Brian O'Connorabafb502014-12-02 22:26:20 -080067import static org.onosproject.net.Device.Type.SWITCH;
68import static org.onosproject.net.DeviceId.deviceId;
Ray Milkeycc53abd2015-02-19 12:31:33 -080069import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
70import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
71import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_UPDATED;
72import static org.onosproject.net.device.DeviceEvent.Type.PORT_ADDED;
73import static org.onosproject.net.device.DeviceEvent.Type.PORT_REMOVED;
74import static org.onosproject.net.device.DeviceEvent.Type.PORT_UPDATED;
tome5ec3fd2014-09-04 15:18:06 -070075
76/**
77 * Test codifying the device service & device provider service contracts.
78 */
tom41a2c5f2014-09-19 09:20:35 -070079public class DeviceManagerTest {
tome5ec3fd2014-09-04 15:18:06 -070080
tom7e02cda2014-09-18 12:05:46 -070081 private static final ProviderId PID = new ProviderId("of", "foo");
tome5ec3fd2014-09-04 15:18:06 -070082 private static final DeviceId DID1 = deviceId("of:foo");
83 private static final DeviceId DID2 = deviceId("of:bar");
84 private static final String MFR = "whitebox";
85 private static final String HW = "1.1.x";
86 private static final String SW1 = "3.8.1";
87 private static final String SW2 = "3.9.5";
88 private static final String SN = "43311-12345";
alshabib7911a052014-10-16 17:49:37 -070089 private static final ChassisId CID = new ChassisId();
tome5ec3fd2014-09-04 15:18:06 -070090
tom24c55cd2014-09-06 10:47:25 -070091 private static final PortNumber P1 = PortNumber.portNumber(1);
92 private static final PortNumber P2 = PortNumber.portNumber(2);
93 private static final PortNumber P3 = PortNumber.portNumber(3);
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -070094 private static final NodeId NID_LOCAL = new NodeId("local");
Pavlin Radoslavov444b5192014-10-28 10:45:19 -070095 private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
tom24c55cd2014-09-06 10:47:25 -070096
tom41a2c5f2014-09-19 09:20:35 -070097 private DeviceManager mgr;
tome5ec3fd2014-09-04 15:18:06 -070098
99 protected DeviceService service;
100 protected DeviceAdminService admin;
101 protected DeviceProviderRegistry registry;
102 protected DeviceProviderService providerService;
103 protected TestProvider provider;
104 protected TestListener listener = new TestListener();
105
106 @Before
107 public void setUp() {
tom41a2c5f2014-09-19 09:20:35 -0700108 mgr = new DeviceManager();
tome5ec3fd2014-09-04 15:18:06 -0700109 service = mgr;
110 admin = mgr;
111 registry = mgr;
tom41a2c5f2014-09-19 09:20:35 -0700112 mgr.store = new SimpleDeviceStore();
tome5ec3fd2014-09-04 15:18:06 -0700113 mgr.eventDispatcher = new TestEventDispatcher();
Yuta HIGUCHIbcac4992014-11-22 19:27:57 -0800114 TestMastershipManager mastershipManager = new TestMastershipManager();
115 mgr.mastershipService = mastershipManager;
116 mgr.termService = mastershipManager;
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700117 mgr.clusterService = new TestClusterService();
Yuta HIGUCHI093e83e2014-10-10 22:26:11 -0700118 mgr.deviceClockProviderService = new TestClockProviderService();
Sahil Lele3a0cdd52015-07-21 14:16:31 -0700119 mgr.networkConfigService = new TestNetworkConfigService();
tome5ec3fd2014-09-04 15:18:06 -0700120 mgr.activate();
121
Sahil Lele3a0cdd52015-07-21 14:16:31 -0700122
tome5ec3fd2014-09-04 15:18:06 -0700123 service.addListener(listener);
124
125 provider = new TestProvider();
126 providerService = registry.register(provider);
127 assertTrue("provider should be registered",
128 registry.getProviders().contains(provider.id()));
129 }
130
131 @After
132 public void tearDown() {
133 registry.unregister(provider);
134 assertFalse("provider should not be registered",
135 registry.getProviders().contains(provider.id()));
136 service.removeListener(listener);
137 mgr.deactivate();
138 }
139
140 private void connectDevice(DeviceId deviceId, String swVersion) {
141 DeviceDescription description =
142 new DefaultDeviceDescription(deviceId.uri(), SWITCH, MFR,
alshabib7911a052014-10-16 17:49:37 -0700143 HW, swVersion, SN, CID);
tome5ec3fd2014-09-04 15:18:06 -0700144 providerService.deviceConnected(deviceId, description);
145 assertNotNull("device should be found", service.getDevice(DID1));
146 }
147
148 @Test
149 public void deviceConnected() {
150 assertNull("device should not be found", service.getDevice(DID1));
151 connectDevice(DID1, SW1);
152 validateEvents(DEVICE_ADDED);
153
154 Iterator<Device> it = service.getDevices().iterator();
155 assertNotNull("one device expected", it.next());
156 assertFalse("only one device expected", it.hasNext());
tomad2d2092014-09-06 23:24:20 -0700157 assertEquals("incorrect device count", 1, service.getDeviceCount());
tomff7eb7c2014-09-08 12:49:03 -0700158 assertTrue("device should be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700159 }
160
161 @Test
162 public void deviceDisconnected() {
163 connectDevice(DID1, SW1);
164 connectDevice(DID2, SW1);
165 validateEvents(DEVICE_ADDED, DEVICE_ADDED);
tomff7eb7c2014-09-08 12:49:03 -0700166 assertTrue("device should be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700167
168 // Disconnect
169 providerService.deviceDisconnected(DID1);
170 assertNotNull("device should not be found", service.getDevice(DID1));
tomff7eb7c2014-09-08 12:49:03 -0700171 assertFalse("device should not be available", service.isAvailable(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700172 validateEvents(DEVICE_AVAILABILITY_CHANGED);
173
174 // Reconnect
175 connectDevice(DID1, SW1);
176 validateEvents(DEVICE_AVAILABILITY_CHANGED);
tomad2d2092014-09-06 23:24:20 -0700177
178 assertEquals("incorrect device count", 2, service.getDeviceCount());
tome5ec3fd2014-09-04 15:18:06 -0700179 }
180
181 @Test
182 public void deviceUpdated() {
183 connectDevice(DID1, SW1);
184 validateEvents(DEVICE_ADDED);
185
186 connectDevice(DID1, SW2);
187 validateEvents(DEVICE_UPDATED);
188 }
189
190 @Test
191 public void getRole() {
192 connectDevice(DID1, SW1);
tom80c0e5e2014-09-08 18:08:58 -0700193 assertEquals("incorrect role", MastershipRole.MASTER, service.getRole(DID1));
tome5ec3fd2014-09-04 15:18:06 -0700194 }
195
tom24c55cd2014-09-06 10:47:25 -0700196 @Test
197 public void updatePorts() {
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 pds.add(new DefaultPortDescription(P3, true));
203 providerService.updatePorts(DID1, pds);
204 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED);
205 pds.clear();
tome5ec3fd2014-09-04 15:18:06 -0700206
tom24c55cd2014-09-06 10:47:25 -0700207 pds.add(new DefaultPortDescription(P1, false));
208 pds.add(new DefaultPortDescription(P3, true));
209 providerService.updatePorts(DID1, pds);
210 validateEvents(PORT_UPDATED, PORT_REMOVED);
211 }
212
213 @Test
214 public void updatePortStatus() {
215 connectDevice(DID1, SW1);
216 List<PortDescription> pds = new ArrayList<>();
217 pds.add(new DefaultPortDescription(P1, true));
218 pds.add(new DefaultPortDescription(P2, true));
219 providerService.updatePorts(DID1, pds);
220 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
221
222 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
223 validateEvents(PORT_UPDATED);
224 providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
225 assertTrue("no events expected", listener.events.isEmpty());
226 }
227
228 @Test
229 public void getPorts() {
230 connectDevice(DID1, SW1);
231 List<PortDescription> pds = new ArrayList<>();
232 pds.add(new DefaultPortDescription(P1, true));
233 pds.add(new DefaultPortDescription(P2, true));
234 providerService.updatePorts(DID1, pds);
235 validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
236 assertEquals("wrong port count", 2, service.getPorts(DID1).size());
237
238 Port port = service.getPort(DID1, P1);
239 assertEquals("incorrect port", P1, service.getPort(DID1, P1).number());
240 assertEquals("incorrect state", true, service.getPort(DID1, P1).isEnabled());
241 }
242
243 @Test
244 public void removeDevice() {
245 connectDevice(DID1, SW1);
246 connectDevice(DID2, SW2);
tomad2d2092014-09-06 23:24:20 -0700247 assertEquals("incorrect device count", 2, service.getDeviceCount());
tom24c55cd2014-09-06 10:47:25 -0700248 admin.removeDevice(DID1);
249 assertNull("device should not be found", service.getDevice(DID1));
250 assertNotNull("device should be found", service.getDevice(DID2));
tomad2d2092014-09-06 23:24:20 -0700251 assertEquals("incorrect device count", 1, service.getDeviceCount());
252
tom24c55cd2014-09-06 10:47:25 -0700253 }
tome5ec3fd2014-09-04 15:18:06 -0700254
255 protected void validateEvents(Enum... types) {
256 int i = 0;
257 assertEquals("wrong events received", types.length, listener.events.size());
258 for (Event event : listener.events) {
259 assertEquals("incorrect event type", types[i], event.type());
260 i++;
261 }
262 listener.events.clear();
263 }
264
265
266 private class TestProvider extends AbstractProvider implements DeviceProvider {
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700267 private DeviceId deviceReceived;
tome5ec3fd2014-09-04 15:18:06 -0700268 private MastershipRole roleReceived;
269
270 public TestProvider() {
271 super(PID);
272 }
273
274 @Override
Ayaka Koshibe78bcbc12014-11-19 14:28:58 -0800275 public void triggerProbe(DeviceId deviceId) {
tome5ec3fd2014-09-04 15:18:06 -0700276 }
277
278 @Override
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700279 public void roleChanged(DeviceId device, MastershipRole newRole) {
tome5ec3fd2014-09-04 15:18:06 -0700280 deviceReceived = device;
281 roleReceived = newRole;
282 }
Ayaka Koshibee60d4522014-10-28 15:07:00 -0700283
284 @Override
Yuta HIGUCHI54815322014-10-31 23:17:08 -0700285 public boolean isReachable(DeviceId device) {
Ayaka Koshibee60d4522014-10-28 15:07:00 -0700286 return false;
287 }
tome5ec3fd2014-09-04 15:18:06 -0700288 }
289
290 private static class TestListener implements DeviceListener {
291 final List<DeviceEvent> events = new ArrayList<>();
292
293 @Override
294 public void event(DeviceEvent event) {
295 events.add(event);
296 }
297 }
298
Yuta HIGUCHIbcac4992014-11-22 19:27:57 -0800299 private static class TestMastershipManager
300 extends MastershipServiceAdapter implements MastershipTermService {
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700301 @Override
tomb41d1ac2014-09-24 01:51:24 -0700302 public MastershipRole getLocalRole(DeviceId deviceId) {
303 return MastershipRole.MASTER;
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700304 }
305
306 @Override
307 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
308 return Sets.newHashSet(DID1, DID2);
309 }
310
311 @Override
Madan Jampanide003d92015-05-11 17:14:20 -0700312 public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
313 return CompletableFuture.completedFuture(MastershipRole.MASTER);
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700314 }
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700315
316 @Override
Madan Jampanic6e574f2015-05-29 13:41:52 -0700317 public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
318 return CompletableFuture.completedFuture(null);
319 }
320
321 @Override
Yuta HIGUCHIbcac4992014-11-22 19:27:57 -0800322 public MastershipTerm getMastershipTerm(DeviceId deviceId) {
323 // FIXME: just returning something not null
324 return MastershipTerm.of(NID_LOCAL, 1);
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700325 }
Ayaka Koshibea7f044e2014-09-23 16:56:20 -0700326 }
327
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700328 // code clone
Ray Milkeycc53abd2015-02-19 12:31:33 -0800329 private final class TestClusterService extends ClusterServiceAdapter {
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700330
331 ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST);
332
333 @Override
334 public ControllerNode getLocalNode() {
335 return local;
336 }
337
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700338 }
339
340 private final class TestClockProviderService implements
Yuta HIGUCHI093e83e2014-10-10 22:26:11 -0700341 DeviceClockProviderService {
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700342
Yuta HIGUCHI13c0b872014-10-30 18:09:22 -0700343 private Set<DeviceId> registerdBefore = Sets.newConcurrentHashSet();
344
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700345 @Override
346 public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) {
Yuta HIGUCHI13c0b872014-10-30 18:09:22 -0700347 registerdBefore.add(deviceId);
348 }
349
350 @Override
351 public boolean isTimestampAvailable(DeviceId deviceId) {
352 return registerdBefore.contains(deviceId);
Yuta HIGUCHI33faeaf2014-10-07 18:19:44 -0700353 }
354 }
Sahil Lele3a0cdd52015-07-21 14:16:31 -0700355
356 private class TestNetworkConfigService extends NetworkConfigServiceAdapter {
357 }
tome5ec3fd2014-09-04 15:18:06 -0700358}