blob: 8b47f448b924e39398b364051a48bc820dc83d72 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.provider.lldp.impl;
alshabib0ed6a202014-10-19 12:42:57 -070017
Ray Milkeycd6ab182016-02-03 11:13:09 -080018import java.nio.ByteBuffer;
19import java.util.Collections;
20import java.util.HashMap;
21import java.util.HashSet;
22import java.util.List;
23import java.util.Map;
24import java.util.Set;
25import java.util.concurrent.CompletableFuture;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080026
alshabib0ed6a202014-10-19 12:42:57 -070027import org.junit.After;
28import org.junit.Before;
29import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080030import org.onlab.packet.ChassisId;
31import org.onlab.packet.Ethernet;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080032import org.onlab.packet.IpAddress;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080033import org.onlab.packet.ONOSLLDP;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070034import org.onosproject.cfg.ComponentConfigAdapter;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080035import org.onosproject.cluster.ClusterMetadata;
Madan Jampaniab7e7cd2016-01-14 14:02:32 -080036import org.onosproject.cluster.ClusterMetadataEventListener;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080037import org.onosproject.cluster.ClusterMetadataService;
38import org.onosproject.cluster.ControllerNode;
39import org.onosproject.cluster.DefaultControllerNode;
Madan Jampani8474fdd2016-01-19 09:56:28 -080040import org.onosproject.cluster.DefaultPartition;
Brian O'Connorabafb502014-12-02 22:26:20 -080041import org.onosproject.cluster.NodeId;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080042import org.onosproject.cluster.Partition;
Madan Jampaniab7e7cd2016-01-14 14:02:32 -080043import org.onosproject.cluster.PartitionId;
Brian O'Connorabafb502014-12-02 22:26:20 -080044import org.onosproject.cluster.RoleInfo;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080045import org.onosproject.core.ApplicationId;
46import org.onosproject.core.CoreService;
47import org.onosproject.core.DefaultApplicationId;
Brian O'Connorabafb502014-12-02 22:26:20 -080048import org.onosproject.mastership.MastershipListener;
49import org.onosproject.mastership.MastershipService;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070050import org.onosproject.net.Annotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080051import org.onosproject.net.ConnectPoint;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070052import org.onosproject.net.DefaultAnnotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080053import org.onosproject.net.DefaultDevice;
54import org.onosproject.net.DefaultPort;
55import org.onosproject.net.Device;
56import org.onosproject.net.DeviceId;
57import org.onosproject.net.MastershipRole;
58import org.onosproject.net.Port;
59import org.onosproject.net.PortNumber;
Naoki Shiota399a0b32015-11-15 20:36:13 -060060import org.onosproject.net.config.Config;
Naoki Shiota399a0b32015-11-15 20:36:13 -060061import org.onosproject.net.config.NetworkConfigEvent;
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -080062import org.onosproject.net.config.NetworkConfigEvent.Type;
Naoki Shiota399a0b32015-11-15 20:36:13 -060063import org.onosproject.net.config.NetworkConfigListener;
64import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080065import org.onosproject.net.device.DeviceEvent;
66import org.onosproject.net.device.DeviceListener;
67import org.onosproject.net.device.DeviceServiceAdapter;
68import org.onosproject.net.flow.TrafficTreatment;
Ray Milkeycd6ab182016-02-03 11:13:09 -080069import org.onosproject.net.link.LinkProviderRegistryAdapter;
70import org.onosproject.net.link.LinkProviderServiceAdapter;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -070071import org.onosproject.net.link.LinkServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080072import org.onosproject.net.packet.DefaultInboundPacket;
73import org.onosproject.net.packet.InboundPacket;
74import org.onosproject.net.packet.OutboundPacket;
75import org.onosproject.net.packet.PacketContext;
76import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska27bee092015-06-23 19:03:10 -070077import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080078import org.onosproject.net.provider.ProviderId;
Ray Milkey957390e2016-02-09 10:02:46 -080079import org.onosproject.provider.lldpcommon.LinkDiscovery;
alshabib0ed6a202014-10-19 12:42:57 -070080
Ray Milkeycd6ab182016-02-03 11:13:09 -080081import com.google.common.collect.ArrayListMultimap;
82import com.google.common.collect.ImmutableList;
83import com.google.common.collect.ImmutableMap;
84import com.google.common.collect.ImmutableSet;
85import com.google.common.collect.Lists;
86import com.google.common.collect.Sets;
Thomas Vachuska27bee092015-06-23 19:03:10 -070087
Naoki Shiota399a0b32015-11-15 20:36:13 -060088import static org.easymock.EasyMock.createMock;
89import static org.easymock.EasyMock.expect;
90import static org.easymock.EasyMock.replay;
Naoki Shiota399a0b32015-11-15 20:36:13 -060091import static org.junit.Assert.assertEquals;
Ray Milkeycd6ab182016-02-03 11:13:09 -080092import static org.junit.Assert.assertFalse;
93import static org.junit.Assert.assertNotNull;
94import static org.junit.Assert.assertNull;
Naoki Shiota399a0b32015-11-15 20:36:13 -060095import static org.junit.Assert.assertTrue;
96import static org.onosproject.provider.lldp.impl.LldpLinkProvider.DEFAULT_RULES;
Naoki Shiota399a0b32015-11-15 20:36:13 -060097
alshabib0ed6a202014-10-19 12:42:57 -070098
Jonathan Hartb35540a2015-11-17 09:30:56 -080099public class LldpLinkProviderTest {
alshabib0ed6a202014-10-19 12:42:57 -0700100
101 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
102 private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002");
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700103 private static final DeviceId DID3 = DeviceId.deviceId("of:0000000000000003");
alshabib0ed6a202014-10-19 12:42:57 -0700104
105 private static Port pd1;
106 private static Port pd2;
107 private static Port pd3;
108 private static Port pd4;
109
Jonathan Hartb35540a2015-11-17 09:30:56 -0800110 private final LldpLinkProvider provider = new LldpLinkProvider();
Ray Milkeycd6ab182016-02-03 11:13:09 -0800111 private final LinkProviderRegistryAdapter linkRegistry = new LinkProviderRegistryAdapter();
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700112 private final TestLinkService linkService = new TestLinkService();
alshabib0ed6a202014-10-19 12:42:57 -0700113 private final TestPacketService packetService = new TestPacketService();
114 private final TestDeviceService deviceService = new TestDeviceService();
115 private final TestMasterShipService masterService = new TestMasterShipService();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600116 private final TestNetworkConfigRegistry configRegistry = new TestNetworkConfigRegistry();
alshabib0ed6a202014-10-19 12:42:57 -0700117
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800118 private CoreService coreService;
Ray Milkeycd6ab182016-02-03 11:13:09 -0800119 private LinkProviderServiceAdapter providerService;
alshabib0ed6a202014-10-19 12:42:57 -0700120
121 private PacketProcessor testProcessor;
122 private DeviceListener deviceListener;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600123 private NetworkConfigListener configListener;
alshabib0ed6a202014-10-19 12:42:57 -0700124
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800125 private ApplicationId appId =
126 new DefaultApplicationId(100, "org.onosproject.provider.lldp");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800127
Naoki Shiota399a0b32015-11-15 20:36:13 -0600128 private TestSuppressionConfig cfg;
129
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800130 private Set<DeviceId> deviceBlacklist;
131
132 private Set<ConnectPoint> portBlacklist;
133
alshabib0ed6a202014-10-19 12:42:57 -0700134 @Before
135 public void setUp() {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800136 deviceBlacklist = new HashSet<>();
137 portBlacklist = new HashSet<>();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600138 cfg = new TestSuppressionConfig();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800139 coreService = createMock(CoreService.class);
140 expect(coreService.registerApplication(appId.name()))
141 .andReturn(appId).anyTimes();
142 replay(coreService);
143
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700144 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800145 provider.coreService = coreService;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600146 provider.cfgRegistry = configRegistry;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800147
alshabib0ed6a202014-10-19 12:42:57 -0700148 provider.deviceService = deviceService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700149 provider.linkService = linkService;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800150 provider.packetService = packetService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700151 provider.providerRegistry = linkRegistry;
alshabib0ed6a202014-10-19 12:42:57 -0700152 provider.masterService = masterService;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800153 provider.clusterMetadataService = new TestMetadataService();
Ray Milkeycd6ab182016-02-03 11:13:09 -0800154
Saurav Dasc313c402015-02-27 10:09:47 -0800155 provider.activate(null);
Ray Milkeycd6ab182016-02-03 11:13:09 -0800156
157 providerService = linkRegistry.registeredProvider();
alshabib0ed6a202014-10-19 12:42:57 -0700158 }
159
160 @Test
161 public void basics() {
162 assertNotNull("registration expected", providerService);
163 assertEquals("incorrect provider", provider, providerService.provider());
164 }
165
166 @Test
167 public void switchAdd() {
168 DeviceEvent de = deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1);
169 deviceListener.event(de);
170
171 assertFalse("Device not added", provider.discoverers.isEmpty());
172 }
173
174 @Test
175 public void switchRemove() {
176 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
177 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1));
178
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700179 final LinkDiscovery linkDiscovery = provider.discoverers.get(DID1);
180 if (linkDiscovery != null) {
181 // If LinkDiscovery helper is there after DEVICE_REMOVED,
182 // it should be stopped
183 assertTrue("Discoverer is not stopped", linkDiscovery.isStopped());
184 }
alshabib0ed6a202014-10-19 12:42:57 -0700185 assertTrue("Device is not gone.", vanishedDpid(DID1));
186 }
187
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700188 /**
189 * Checks that links on a reconfigured switch are properly removed.
190 */
191 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800192 public void switchSuppressedByAnnotation() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600193
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700194 // add device to stub DeviceService
195 deviceService.putDevice(device(DID3));
196 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
197
198 assertFalse("Device not added", provider.discoverers.isEmpty());
199
200 // update device in stub DeviceService with suppression config
201 deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800202 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700203 .build()));
204 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
205
Naoki Shiota399a0b32015-11-15 20:36:13 -0600206 // discovery on device is expected to be gone or stopped
207 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
208 if (linkDiscovery != null) {
209 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
210 }
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700211 }
212
alshabib0ed6a202014-10-19 12:42:57 -0700213 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800214 public void switchSuppressByBlacklist() {
215 // add device in stub DeviceService
216 deviceService.putDevice(device(DID3));
217 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
218
219 // add deviveId to device blacklist
220 deviceBlacklist.add(DID3);
221 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
222 DID3,
223 LinkDiscoveryFromDevice.class));
224
225 // discovery helper for device is expected to be gone or stopped
226 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
227 if (linkDiscovery != null) {
228 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
229 }
230
231 }
232
233 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700234 public void portUp() {
235 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
236 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
237
238 assertTrue("Port not added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700239 provider.discoverers.get(DID1).containsPort(3L));
alshabib0ed6a202014-10-19 12:42:57 -0700240 }
241
242 @Test
243 public void portDown() {
244
245 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
246 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
247
alshabib0ed6a202014-10-19 12:42:57 -0700248 assertFalse("Port added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700249 provider.discoverers.get(DID1).containsPort(1L));
250 assertTrue("Port is not gone.", vanishedPort(1L));
alshabib0ed6a202014-10-19 12:42:57 -0700251 }
252
253 @Test
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700254 public void portRemoved() {
255 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
256 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
257 deviceListener.event(portEvent(DeviceEvent.Type.PORT_REMOVED, DID1, port(DID1, 3, true)));
258
259 assertTrue("Port is not gone.", vanishedPort(3L));
260 assertFalse("Port was not removed from discoverer",
261 provider.discoverers.get(DID1).containsPort(3L));
262 }
263
264 /**
265 * Checks that discovery on reconfigured switch are properly restarted.
266 */
267 @Test
Naoki Shiota399a0b32015-11-15 20:36:13 -0600268 public void portSuppressedByDeviceAnnotationConfig() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700269
270 /// When Device is configured with suppression:ON, Port also is same
271
272 // add device in stub DeviceService with suppression configured
273 deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800274 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700275 .build()));
276 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
277
278 // non-suppressed port added to suppressed device
279 final long portno3 = 3L;
280 deviceService.putPorts(DID3, port(DID3, portno3, true));
281 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
282
283 // discovery on device is expected to be stopped
284 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
285 if (linkDiscovery != null) {
286 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
287 }
288
289 /// When Device is reconfigured without suppression:OFF,
290 /// Port should be included for discovery
291
292 // update device in stub DeviceService without suppression configured
293 deviceService.putDevice(device(DID3));
294 // update the Port in stub DeviceService. (Port has reference to Device)
295 deviceService.putPorts(DID3, port(DID3, portno3, true));
296 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
297
298 // discovery should come back on
299 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
300 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
301 }
302
303 /**
Naoki Shiota399a0b32015-11-15 20:36:13 -0600304 * Checks that discovery on reconfigured switch are properly restarted.
305 */
306 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800307 public void portSuppressedByParentDeviceIdBlacklist() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600308
309 /// When Device is configured without suppression:OFF,
310 /// Port should be included for discovery
311
312 // add device in stub DeviceService without suppression configured
313 deviceService.putDevice(device(DID3));
314 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
315
316 // non-suppressed port added to suppressed device
317 final long portno3 = 3L;
318 deviceService.putPorts(DID3, port(DID3, portno3, true));
319 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
320
321 // discovery should succeed
322 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
323 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
324
325 // add suppression rule for "deviceId: "of:0000000000000003""
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800326 deviceBlacklist.add(DID3);
327 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
328 DID3,
329 LinkDiscoveryFromDevice.class));
330
Naoki Shiota399a0b32015-11-15 20:36:13 -0600331
332 /// When Device is reconfigured with suppression:ON, Port also is same
333
334 // update device in stub DeviceService with suppression configured
335 deviceService.putDevice(device(DID3));
336 // update the Port in stub DeviceService. (Port has reference to Device)
337 deviceService.putPorts(DID3, port(DID3, portno3, true));
338 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
339
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800340 // discovery helper for device is expected to be gone or stopped
Naoki Shiota399a0b32015-11-15 20:36:13 -0600341 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
342 if (linkDiscovery != null) {
343 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
344 }
345 }
346
347 /**
348 * Checks that discovery on reconfigured switch are properly restarted.
349 */
350 @Test
351 public void portSuppressedByDeviceTypeConfig() {
352
353 /// When Device is configured without suppression:OFF,
354 /// Port should be included for discovery
355
356 // add device in stub DeviceService without suppression configured
357 deviceService.putDevice(device(DID1, Device.Type.SWITCH));
358 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
359
360 // non-suppressed port added to suppressed device
361 final long portno3 = 3L;
362 deviceService.putPorts(DID1, port(DID1, portno3, true));
363 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, portno3, true)));
364
365 // add device in stub DeviceService with suppression configured
366 deviceService.putDevice(device(DID2, Device.Type.ROADM));
367 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
368
369 // non-suppressed port added to suppressed device
370 final long portno4 = 4L;
371 deviceService.putPorts(DID2, port(DID2, portno4, true));
372 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, portno4, true)));
373
374 // discovery should succeed for this device
375 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID1).isStopped());
376 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID1).containsPort(portno3));
377
378 // discovery on device is expected to be stopped for this device
379 LinkDiscovery linkDiscovery = provider.discoverers.get(DID2);
380 if (linkDiscovery != null) {
381 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
382 }
383 }
384
385 /**
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700386 * Checks that discovery on reconfigured port are properly restarted.
387 */
388 @Test
389 public void portSuppressedByPortConfig() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600390
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700391 // add device in stub DeviceService without suppression configured
392 deviceService.putDevice(device(DID3));
393 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
394
395 // suppressed port added to non-suppressed device
396 final long portno3 = 3L;
397 final Port port3 = port(DID3, portno3, true,
398 DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800399 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700400 .build());
401 deviceService.putPorts(DID3, port3);
402 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
403
404 // discovery helper should be there turned on
405 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
406 assertFalse("Discoverer should not contain the port there",
407 provider.discoverers.get(DID3).containsPort(portno3));
408 }
409
410 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800411 public void portSuppressedByPortBlacklist() {
412
413 // add device in stub DeviceService without suppression configured
414 deviceService.putDevice(device(DID3));
415 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
416
417 final long portno3 = 3L;
418 final Port port3 = port(DID3, portno3, true);
419
420 final ConnectPoint cpDid3no3 = new ConnectPoint(DID3, PortNumber.portNumber(portno3));
421 portBlacklist.add(cpDid3no3);
422
423 // suppressed port added to non-suppressed device
424 deviceService.putPorts(DID3, port3);
425 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
426
427 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
428 cpDid3no3,
429 LinkDiscoveryFromPort.class));
430
431 // discovery helper should be there turned on
432 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
433 // but port is not a discovery target
434 assertFalse("Discoverer should not contain the port there",
435 provider.discoverers.get(DID3).containsPort(portno3));
436 }
437
438 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700439 public void portUnknown() {
440 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700441 // Note: DID3 hasn't been added to TestDeviceService, but only port is added
442 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, 1, false)));
alshabib0ed6a202014-10-19 12:42:57 -0700443
444
alshabibdfc7afb2014-10-21 20:13:27 -0700445 assertNull("DeviceId exists",
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700446 provider.discoverers.get(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700447 }
448
449 @Test
450 public void unknownPktCtx() {
451
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700452 // Note: DID3 hasn't been added to TestDeviceService
453 PacketContext pktCtx = new TestPacketContext(device(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700454
455 testProcessor.process(pktCtx);
456 assertFalse("Context should still be free", pktCtx.isHandled());
457 }
458
459 @Test
460 public void knownPktCtx() {
461 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
462 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
463 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
464
465
466 testProcessor.process(pktCtx);
467
468 assertTrue("Link not detected", detectedLink(DID1, DID2));
469
470 }
471
472
473 @After
474 public void tearDown() {
475 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800476 provider.coreService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700477 provider.providerRegistry = null;
478 provider.deviceService = null;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800479 provider.packetService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700480 }
481
482 private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
483 return new DeviceEvent(type, deviceService.getDevice(did));
484
485 }
486
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700487 private DefaultDevice device(DeviceId did) {
488 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
489 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
490 }
491
Naoki Shiota399a0b32015-11-15 20:36:13 -0600492 private DefaultDevice device(DeviceId did, Device.Type type) {
493 return new DefaultDevice(ProviderId.NONE, did, type,
494 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
495 }
496
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700497 private DefaultDevice device(DeviceId did, Annotations annotations) {
498 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
499 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId(), annotations);
500 }
501
Saurav Dasc313c402015-02-27 10:09:47 -0800502 @SuppressWarnings(value = { "unused" })
alshabib0ed6a202014-10-19 12:42:57 -0700503 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
504 return new DeviceEvent(type, deviceService.getDevice(did),
505 deviceService.getPort(did, port));
506 }
507
508 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) {
509 return new DeviceEvent(type, deviceService.getDevice(did), port);
510 }
511
512 private Port port(DeviceId did, long port, boolean enabled) {
513 return new DefaultPort(deviceService.getDevice(did),
514 PortNumber.portNumber(port), enabled);
515 }
516
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700517 private Port port(DeviceId did, long port, boolean enabled, Annotations annotations) {
518 return new DefaultPort(deviceService.getDevice(did),
519 PortNumber.portNumber(port), enabled, annotations);
520 }
alshabib0ed6a202014-10-19 12:42:57 -0700521
522 private boolean vanishedDpid(DeviceId... dids) {
523 for (int i = 0; i < dids.length; i++) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800524 if (!providerService.vanishedDpid().contains(dids[i])) {
alshabib0ed6a202014-10-19 12:42:57 -0700525 return false;
526 }
527 }
528 return true;
529 }
530
531 private boolean vanishedPort(Long... ports) {
532 for (int i = 0; i < ports.length; i++) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800533 if (!providerService.vanishedPort().contains(ports[i])) {
alshabib0ed6a202014-10-19 12:42:57 -0700534 return false;
535 }
536 }
537 return true;
538 }
539
540 private boolean detectedLink(DeviceId src, DeviceId dst) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800541 for (DeviceId key : providerService.discoveredLinks().keySet()) {
alshabib0ed6a202014-10-19 12:42:57 -0700542 if (key.equals(src)) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800543 return providerService.discoveredLinks().get(src).equals(dst);
alshabib0ed6a202014-10-19 12:42:57 -0700544 }
545 }
546 return false;
547 }
548
Naoki Shiota399a0b32015-11-15 20:36:13 -0600549 @Test
550 public void addDeviceTypeRule() {
551 Device.Type deviceType1 = Device.Type.ROADM;
552 Device.Type deviceType2 = Device.Type.SWITCH;
553
554 Set<Device.Type> deviceTypes = new HashSet<>();
555 deviceTypes.add(deviceType1);
556
557 cfg.deviceTypes(deviceTypes);
558
559 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
560
561 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
562 assertFalse(provider.rules().getSuppressedDeviceType().contains(deviceType2));
563 }
564
565 @Test
566 public void updateDeviceTypeRule() {
567 Device.Type deviceType1 = Device.Type.ROADM;
568 Device.Type deviceType2 = Device.Type.SWITCH;
569 Set<Device.Type> deviceTypes = new HashSet<>();
570
571 deviceTypes.add(deviceType1);
572 cfg.deviceTypes(deviceTypes);
573
574 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
575
576 deviceTypes.add(deviceType2);
577 cfg.deviceTypes(deviceTypes);
578
579 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
580
581 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
582 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType2));
583 }
584
585 @Test
586 public void addAnnotationRule() {
587 final String key1 = "key1", key2 = "key2";
588 final String value1 = "value1";
589
590 Map<String, String> annotation = new HashMap<>();
591 annotation.put(key1, value1);
592
593 cfg.annotation(annotation);
594
595 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
596
597 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
598 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
599 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
600 }
601
602 @Test
603 public void updateAnnotationRule() {
604 final String key1 = "key1", key2 = "key2";
605 final String value1 = "value1", value2 = "value2";
606 Map<String, String> annotation = new HashMap<>();
607
608 annotation.put(key1, value1);
609 cfg.annotation(annotation);
610
611 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
612
613 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
614 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
615 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
616
617 annotation.put(key2, value2);
618 cfg.annotation(annotation);
619
620 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
621
622 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
623 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
624 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key2));
625 assertEquals(value2, provider.rules().getSuppressedAnnotation().get(key2));
626 }
627
628 private void configEvent(NetworkConfigEvent.Type evType) {
629 configListener.event(new NetworkConfigEvent(evType,
630 appId,
631 SuppressionConfig.class));
632 }
633
alshabib0ed6a202014-10-19 12:42:57 -0700634 private class TestPacketContext implements PacketContext {
635
636 protected Device device;
637 protected boolean blocked = false;
638
639 public TestPacketContext(Device dev) {
640 device = dev;
641 }
642
643 @Override
644 public long time() {
645 return 0;
646 }
647
648 @Override
649 public InboundPacket inPacket() {
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800650 ONOSLLDP lldp = ONOSLLDP.onosLLDP(deviceService.getDevice(DID1).id().toString(),
651 device.chassisId(),
652 (int) pd1.number().toLong());
alshabib0ed6a202014-10-19 12:42:57 -0700653
654 Ethernet ethPacket = new Ethernet();
655 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
656 ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA);
657 ethPacket.setPayload(lldp);
658 ethPacket.setPad(true);
659
alshabib0ed6a202014-10-19 12:42:57 -0700660 ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
661
662 ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
663
664 return new DefaultInboundPacket(cp, ethPacket,
665 ByteBuffer.wrap(ethPacket.serialize()));
666
667 }
668
669 @Override
670 public OutboundPacket outPacket() {
671 return null;
672 }
673
674 @Override
675 public TrafficTreatment.Builder treatmentBuilder() {
676 return null;
677 }
678
679 @Override
680 public void send() {
681
682 }
683
684 @Override
685 public boolean block() {
686 blocked = true;
687 return blocked;
688 }
689
690 @Override
691 public boolean isHandled() {
692 return blocked;
693 }
694
695 }
696
Thomas Vachuska27bee092015-06-23 19:03:10 -0700697 private class TestPacketService extends PacketServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700698 @Override
699 public void addProcessor(PacketProcessor processor, int priority) {
700 testProcessor = processor;
701 }
alshabib0ed6a202014-10-19 12:42:57 -0700702 }
703
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800704 private class TestDeviceService extends DeviceServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700705
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700706 private final Map<DeviceId, Device> devices = new HashMap<>();
alshabib0ed6a202014-10-19 12:42:57 -0700707 private final ArrayListMultimap<DeviceId, Port> ports =
708 ArrayListMultimap.create();
alshabib0ed6a202014-10-19 12:42:57 -0700709 public TestDeviceService() {
710 Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH,
711 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
712 Device d2 = new DefaultDevice(ProviderId.NONE, DID2, Device.Type.SWITCH,
713 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
714 devices.put(DID1, d1);
715 devices.put(DID2, d2);
alshabib0ed6a202014-10-19 12:42:57 -0700716 pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true);
717 pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true);
718 pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true);
719 pd4 = new DefaultPort(d2, PortNumber.portNumber(2), true);
720
721 ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
722 ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
alshabib0ed6a202014-10-19 12:42:57 -0700723 }
724
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700725 private void putDevice(Device device) {
726 DeviceId deviceId = device.id();
727 devices.put(deviceId, device);
728 }
729
730 private void putPorts(DeviceId did, Port...ports) {
731 this.ports.putAll(did, Lists.newArrayList(ports));
732 }
733
alshabib0ed6a202014-10-19 12:42:57 -0700734 @Override
735 public int getDeviceCount() {
736 return devices.values().size();
737 }
738
739 @Override
740 public Iterable<Device> getDevices() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700741 return ImmutableList.copyOf(devices.values());
alshabib0ed6a202014-10-19 12:42:57 -0700742 }
743
744 @Override
745 public Device getDevice(DeviceId deviceId) {
746 return devices.get(deviceId);
747 }
748
749 @Override
750 public MastershipRole getRole(DeviceId deviceId) {
751 return MastershipRole.MASTER;
752 }
753
754 @Override
755 public List<Port> getPorts(DeviceId deviceId) {
756 return ports.get(deviceId);
757 }
758
759 @Override
760 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
761 for (Port p : ports.get(deviceId)) {
762 if (p.number().equals(portNumber)) {
763 return p;
764 }
765 }
766 return null;
767 }
768
769 @Override
770 public boolean isAvailable(DeviceId deviceId) {
771 return true;
772 }
773
774 @Override
775 public void addListener(DeviceListener listener) {
776 deviceListener = listener;
777
778 }
779
780 @Override
781 public void removeListener(DeviceListener listener) {
782
783 }
784 }
785
786 private final class TestMasterShipService implements MastershipService {
787
788 @Override
789 public MastershipRole getLocalRole(DeviceId deviceId) {
790 return MastershipRole.MASTER;
791 }
792
793 @Override
Madan Jampanide003d92015-05-11 17:14:20 -0700794 public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
795 return CompletableFuture.completedFuture(null);
alshabib0ed6a202014-10-19 12:42:57 -0700796 }
797
798 @Override
Madan Jampanic6e574f2015-05-29 13:41:52 -0700799 public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
800 return null;
alshabib0ed6a202014-10-19 12:42:57 -0700801 }
802
803 @Override
804 public NodeId getMasterFor(DeviceId deviceId) {
805 return null;
806 }
807
808 @Override
809 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
810 return null;
811 }
812
813 @Override
alshabib0ed6a202014-10-19 12:42:57 -0700814 public void addListener(MastershipListener listener) {
815
816 }
817
818 @Override
819 public void removeListener(MastershipListener listener) {
820
821 }
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700822
823 @Override
Ayaka Koshibeabedb092014-10-20 17:01:31 -0700824 public RoleInfo getNodesFor(DeviceId deviceId) {
825 return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList());
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700826 }
alshabib0ed6a202014-10-19 12:42:57 -0700827 }
828
829
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700830 private class TestLinkService extends LinkServiceAdapter {
831 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600832
833 private final class TestNetworkConfigRegistry
834 extends NetworkConfigRegistryAdapter {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800835 @SuppressWarnings("unchecked")
Naoki Shiota399a0b32015-11-15 20:36:13 -0600836 @Override
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800837 public <S, C extends Config<S>> C getConfig(S subj, Class<C> configClass) {
838 if (configClass == SuppressionConfig.class) {
839 return (C) cfg;
840 } else if (configClass == LinkDiscoveryFromDevice.class) {
841 return (C) new LinkDiscoveryFromDevice() {
842 @Override
843 public boolean enabled() {
844 return !deviceBlacklist.contains(subj);
845 }
846 };
847 } else if (configClass == LinkDiscoveryFromPort.class) {
848 return (C) new LinkDiscoveryFromPort() {
849 @Override
850 public boolean enabled() {
851 return !portBlacklist.contains(subj);
852 }
853 };
854 } else {
855 return null;
856 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600857 }
858
859 @Override
860 public void addListener(NetworkConfigListener listener) {
861 configListener = listener;
862 }
863 }
864
865 private final class TestSuppressionConfig extends SuppressionConfig {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600866 private Set<Device.Type> deviceTypes = new HashSet<>(DEFAULT_RULES.getSuppressedDeviceType());
867 private Map<String, String> annotation = new HashMap<>(DEFAULT_RULES.getSuppressedAnnotation());
868
869 @Override
Naoki Shiota399a0b32015-11-15 20:36:13 -0600870 public Set<Device.Type> deviceTypes() {
871 return ImmutableSet.copyOf(deviceTypes);
872 }
873
874 @Override
875 public SuppressionConfig deviceTypes(Set<Device.Type> deviceTypes) {
876 this.deviceTypes = ImmutableSet.copyOf(deviceTypes);
877 return this;
878 }
879
880 @Override
881 public Map<String, String> annotation() {
882 return ImmutableMap.copyOf(annotation);
883 }
884
885 @Override
886 public SuppressionConfig annotation(Map<String, String> annotation) {
887 this.annotation = ImmutableMap.copyOf(annotation);
888 return this;
889 }
890 }
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800891
892 private final class TestMetadataService implements ClusterMetadataService {
893 @Override
894 public ClusterMetadata getClusterMetadata() {
895 final NodeId nid = new NodeId("test-node");
896 final IpAddress addr = IpAddress.valueOf(0);
Madan Jampani8474fdd2016-01-19 09:56:28 -0800897 final Partition p = new DefaultPartition(PartitionId.from(1), Sets.newHashSet(nid));
Madan Jampaniad3c5262016-01-20 00:50:17 -0800898 return new ClusterMetadata("test-cluster",
899 Sets.newHashSet(new DefaultControllerNode(nid, addr)),
900 Sets.newHashSet(p));
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800901 }
902
903 @Override
Madan Jampaniab7e7cd2016-01-14 14:02:32 -0800904 public ControllerNode getLocalNode() {
905 return null;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800906 }
907
908 @Override
Madan Jampaniab7e7cd2016-01-14 14:02:32 -0800909 public void addListener(ClusterMetadataEventListener listener) {
910 }
911
912 @Override
913 public void removeListener(ClusterMetadataEventListener listener) {
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800914 }
915 }
alshabib0ed6a202014-10-19 12:42:57 -0700916}